]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Fix the shared memory caching issues in util_ldap PR #18756
authorBradley Nicholes <bnicholes@apache.org>
Wed, 11 Feb 2004 18:07:46 +0000 (18:07 +0000)
committerBradley Nicholes <bnicholes@apache.org>
Wed, 11 Feb 2004 18:07:46 +0000 (18:07 +0000)
Submitted by: Matthieu Estrade, Brad Nicholes
Reviewed by: Mathieu Estrade, Brad Nicholes, Jeff Trawick

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/APACHE_2_0_BRANCH@102632 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
include/util_ldap.h
modules/experimental/util_ldap.c
modules/experimental/util_ldap_cache.c
modules/experimental/util_ldap_cache.h
modules/experimental/util_ldap_cache_mgr.c

diff --git a/CHANGES b/CHANGES
index e2d178b6e1bba3ccba6cf659b7f58223a0e4fa2f..dff81bf84d388b17438d102966d755e59253c5c6 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,8 @@
 Changes with Apache 2.0.49
 
+  *) mod_auth_ldap: Fix some segfaults in the cache logic.  PR 18756.
+     [Matthieu Estrade <apache moresecurity.org>, Brad Nicholes]
+
   *) mod_cgid: Restart the cgid daemon if it crashes.  PR 19849
      [Glenn Nielsen <glenn apache.org>]
 
diff --git a/STATUS b/STATUS
index 53c3d0ca6d1b81724b9e4e3b722e3099ba1de3d8..e5edeb72f24023c1954de73524ad9e7c23a26cb1 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -1,5 +1,5 @@
 APACHE 2.0 STATUS:                                              -*-text-*-
-Last modified at [$Date: 2004/02/10 14:53:27 $]
+Last modified at [$Date: 2004/02/11 18:07:45 $]
 
 Release:
 
@@ -230,17 +230,6 @@ PATCHES TO BACKPORT FROM 2.1
          nd replies: But if it can't be 0 the alternatives thereafter make no
            sense anymore, right?
 
-    * LDAP cache fixes from Matthieu Estrade; see PR 18756
-        include/util_ldap.h r1.12
-        modules/experimental/util_ldap.c r1.15, r1.16
-        modules/experimental/util_ldap_cache.c r1.9, r1.10
-        modules/experimental/util_ldap_cache.h r1.7, r1.8
-        modules/experimental/util_ldap_cache_mgr.c r1.6, r1.7, r1.8, r1.10
-      +1: trawick (this stuff can sure use more eyes, but some users 
-                   have already tested the patch successfully)
-         bnicholes (looks good on Netware but then NetWare does not
-                    use shared memory.)
-
     * mod_auth_digest: Allow sub-requests with different methods than the
       original request.  PR 25040.
         modules/aaa/mod_auth_digest.c: r1.82
index 38f4944228e6712cc9706c932eebadd04a513b56..4f9c24f8cdb75a1463c0190e3bfddc4a99598070 100644 (file)
 #include "http_protocol.h"
 #include "http_request.h"
 
+#if APR_HAS_SHARED_MEMORY
+#include "apr_rmm.h"
+#include "apr_shm.h"
+#endif
 
 /* Create a set of LDAP_DECLARE(type), LDLDAP_DECLARE(type) and 
  * LDAP_DECLARE_DATA with appropriate export and import tags for the platform
@@ -58,7 +62,6 @@
 #define LDAP_DECLARE_DATA             __declspec(dllimport)
 #endif
 
-
 /*
  * LDAP Connections
  */
@@ -99,9 +102,11 @@ typedef struct util_ldap_state_t {
     apr_pool_t *pool;           /* pool from which this state is allocated */
 #if APR_HAS_THREADS
     apr_thread_mutex_t *mutex;          /* mutex lock for the connection list */
+    apr_thread_rwlock_t *util_ldap_cache_lock;
 #endif
 
     apr_size_t cache_bytes;     /* Size (in bytes) of shared memory cache */
+    char *cache_file;           /* filename for shm */
     long search_cache_ttl;      /* TTL for search cache */
     long search_cache_size;     /* Size (in entries) of search cache */
     long compare_cache_ttl;     /* TTL for compare cache */
@@ -111,6 +116,15 @@ typedef struct util_ldap_state_t {
     char *cert_auth_file; 
     int   cert_file_type;
     int   ssl_support;
+
+#if APR_HAS_SHARED_MEMORY
+    apr_shm_t *cache_shm;
+    apr_rmm_t *cache_rmm;
+#endif
+
+    /* cache ald */
+    void *util_ldap_cache;
+
 } util_ldap_state_t;
 
 
@@ -247,21 +261,21 @@ LDAP_DECLARE(int) util_ldap_ssl_supported(request_rec *r);
  * @param reqsize The size of the shared memory segement to request. A size
  *                of zero requests the max size possible from
  *                apr_shmem_init()
- * @deffunc void util_ldap_cache_init(apr_pool_t *p)
+ * @deffunc void util_ldap_cache_init(apr_pool_t *p, util_ldap_state_t *st)
  * @return The status code returned is the status code of the
  *         apr_smmem_init() call. Regardless of the status, the cache
  *         will be set up at least for in-process or in-thread operation.
  */
-apr_status_t util_ldap_cache_init(apr_pool_t *pool, apr_size_t reqsize);
+apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st);
 
 /**
  * Display formatted stats for cache
  * @param The pool to allocate the returned string from
  * @tip This function returns a string allocated from the provided pool that describes
  *      various stats about the cache.
- * @deffunc char *util_ald_cache_display(apr_pool_t *pool)
+ * @deffunc char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st)
  */
-char *util_ald_cache_display(apr_pool_t *pool);
+char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st);
 
 
 /* from apr_ldap_cache_mgr.c */
@@ -271,9 +285,9 @@ char *util_ald_cache_display(apr_pool_t *pool);
  * @param The pool to allocate the returned string from
  * @tip This function returns a string allocated from the provided pool that describes
  *      various stats about the cache.
- * @deffunc char *util_ald_cache_display(apr_pool_t *pool)
+ * @deffunc char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st)
  */
-char *util_ald_cache_display(apr_pool_t *pool);
+char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st);
 
 #endif /* APU_HAS_LDAP */
 #endif /* UTIL_LDAP_H */
index 2890abad4a194c6ff49cc4ce13d6f8befa946303..2f2d3e1b3d7ac11bbc8b3d12bd958e5b727282ef 100644 (file)
@@ -102,6 +102,7 @@ void *util_ldap_create_config(apr_pool_t *p, server_rec *s);
  */
 int util_ldap_handler(request_rec *r)
 {
+    util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module);
 
     r->allowed |= (1 << M_GET);
     if (r->method_number != M_GET)
@@ -132,7 +133,7 @@ int util_ldap_handler(request_rec *r)
              "</tr>\n", r
             );
 
-    ap_rputs(util_ald_cache_display(r->pool), r);
+    ap_rputs(util_ald_cache_display(r->pool, st), r);
 
     ap_rputs("</table>\n</p>\n", r);
 
@@ -467,9 +468,7 @@ LDAP_DECLARE(int) util_ldap_cache_comparedn(request_rec *r, util_ldap_connection
     LDAPMessage *res, *entry;
     char *searchdn;
 
-    util_ldap_state_t *st = 
-        (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
-        &ldap_module);
+    util_ldap_state_t *st =  (util_ldap_state_t *)ap_get_module_config(r->server->module_config, &ldap_module);
 
     /* read lock this function */
     LDAP_CACHE_LOCK_CREATE(st->pool);
@@ -478,7 +477,7 @@ LDAP_DECLARE(int) util_ldap_cache_comparedn(request_rec *r, util_ldap_connection
     LDAP_CACHE_WRLOCK();
 
     curnode.url = url;
-    curl = util_ald_cache_fetch(util_ldap_cache, &curnode);
+    curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode);
     if (curl == NULL) {
         curl = util_ald_create_caches(st, url);
     }
@@ -598,7 +597,7 @@ LDAP_DECLARE(int) util_ldap_cache_compare(request_rec *r, util_ldap_connection_t
     /* get cache entry (or create one) */
     LDAP_CACHE_WRLOCK();
     curnode.url = url;
-    curl = util_ald_cache_fetch(util_ldap_cache, &curnode);
+    curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode);
     if (curl == NULL) {
         curl = util_ald_create_caches(st, url);
     }
@@ -721,7 +720,7 @@ LDAP_DECLARE(int) util_ldap_cache_checkuserid(request_rec *r, util_ldap_connecti
     /* Get the cache node for this url */
     LDAP_CACHE_WRLOCK();
     curnode.url = url;
-    curl = (util_url_node_t *)util_ald_cache_fetch(util_ldap_cache, &curnode);
+    curl = (util_url_node_t *)util_ald_cache_fetch(st->util_ldap_cache, &curnode);
     if (curl == NULL) {
         curl = util_ald_create_caches(st, url);
     }
@@ -923,6 +922,26 @@ static const char *util_ldap_set_cache_bytes(cmd_parms *cmd, void *dummy, const
     return NULL;
 }
 
+static const char *util_ldap_set_cache_file(cmd_parms *cmd, void *dummy, const char *file)
+{
+    util_ldap_state_t *st = 
+        (util_ldap_state_t *)ap_get_module_config(cmd->server->module_config, 
+                                                  &ldap_module);
+
+    if (file) {
+        st->cache_file = ap_server_root_relative(st->pool, file);
+    }
+    else {
+        st->cache_file = NULL;
+    }
+
+    ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, cmd->server, 
+                 "LDAP cache: Setting shared memory cache file to %s bytes.", 
+                 st->cache_file);
+
+    return NULL;
+}
+
 static const char *util_ldap_set_cache_ttl(cmd_parms *cmd, void *dummy, const char *ttl)
 {
     util_ldap_state_t *st = 
@@ -1052,22 +1071,6 @@ void *util_ldap_create_config(apr_pool_t *p, server_rec *s)
     return st;
 }
 
-static void util_ldap_init_module(apr_pool_t *pool, server_rec *s)
-{
-    util_ldap_state_t *st = 
-        (util_ldap_state_t *)ap_get_module_config(s->module_config, 
-                                                 &ldap_module);
-
-    apr_status_t result = util_ldap_cache_init(pool, st->cache_bytes);
-    char buf[MAX_STRING_LEN];
-
-    apr_strerror(result, buf, sizeof(buf));
-    ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, result, s, 
-                      "[%d] ldap cache init: %s", 
-                      getpid(), buf);
-}
-
-
 static apr_status_t util_ldap_cleanup_module(void *data)
 {
     server_rec *s = data;
@@ -1089,13 +1092,46 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
                                  apr_pool_t *ptemp, server_rec *s)
 {
     int rc = LDAP_SUCCESS;
+    apr_status_t result;
+    char buf[MAX_STRING_LEN];
 
-    util_ldap_state_t *st = (util_ldap_state_t *)ap_get_module_config(
-                                                s->module_config, 
-                                                &ldap_module);
+    util_ldap_state_t *st =
+        (util_ldap_state_t *)ap_get_module_config(s->module_config, &ldap_module);
 
-        /* log the LDAP SDK used 
-        */
+#if APR_HAS_SHARED_MEMORY
+    server_rec *s_vhost;
+    util_ldap_state_t *st_vhost;
+    
+    /* initializing cache if file is here and we already don't have shm addr*/
+    if (st->cache_file && !st->cache_shm) {
+#endif
+        result = util_ldap_cache_init(p, st);
+        apr_strerror(result, buf, sizeof(buf));
+        ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, result, s,
+                     "LDAP cache init: %s", buf);
+
+#if APR_HAS_SHARED_MEMORY
+        /* merge config in all vhost */
+        s_vhost = s->next;
+        while (s_vhost) {
+            ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, result, s, 
+                         "LDAP merging Shared Cache conf: shm=0x%x rmm=0x%x for VHOST: %s",
+                         st->cache_shm, st->cache_rmm, s_vhost->server_hostname);
+
+            st_vhost = (util_ldap_state_t *)ap_get_module_config(s_vhost->module_config, &ldap_module);
+            st_vhost->cache_shm = st->cache_shm;
+            st_vhost->cache_rmm = st->cache_rmm;
+            st_vhost->cache_file = st->cache_file;
+            s_vhost = s_vhost->next;
+        }
+    }
+    else {
+        ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0 , s, "LDAP cache: Unable to init Shared Cache: no file");
+    }
+#endif
+    
+    /* log the LDAP SDK used 
+     */
     #if APR_HAS_NETSCAPE_LDAPSDK 
     
         ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, 
@@ -1258,6 +1294,10 @@ command_rec util_ldap_cmds[] = {
                   "Sets the size of the shared memory cache in bytes. "
                   "Zero means disable the shared memory cache. Defaults to 100KB."),
 
+    AP_INIT_TAKE1("LDAPSharedCacheFile", util_ldap_set_cache_file, NULL, RSRC_CONF,
+                  "Sets the file of the shared memory cache."
+                  "Nothing means disable the shared memory cache."),
+
     AP_INIT_TAKE1("LDAPCacheEntries", util_ldap_set_cache_entries, NULL, RSRC_CONF,
                   "Sets the maximum number of entries that are possible in the LDAP "
                   "search cache. "
@@ -1292,7 +1332,6 @@ command_rec util_ldap_cmds[] = {
 static void util_ldap_register_hooks(apr_pool_t *p)
 {
     ap_hook_post_config(util_ldap_post_config,NULL,NULL,APR_HOOK_MIDDLE);
-    ap_hook_child_init(util_ldap_init_module, NULL, NULL, APR_HOOK_MIDDLE);
     ap_hook_handler(util_ldap_handler, NULL, NULL, APR_HOOK_MIDDLE);
 }
 
index f7f333c68418b1c431e6752e3e671dd1216b9ca3..a279a57e0104e8b631e0fdec1179ad70ca2e9271 100644 (file)
@@ -27,8 +27,9 @@
 
 #ifdef APU_HAS_LDAP
 
+#if APR_HAS_SHARED_MEMORY
 #define MODLDAP_SHMEM_CACHE "/tmp/mod_ldap_cache"
-
+#endif
 
 /* ------------------------------------------------------------------ */
 
@@ -46,14 +47,14 @@ int util_ldap_url_node_compare(void *a, void *b)
     return(strcmp(na->url, nb->url) == 0);
 }
 
-void *util_ldap_url_node_copy(void *c)
+void *util_ldap_url_node_copy(util_ald_cache_t *cache, void *c)
 {
     util_url_node_t *n = (util_url_node_t *)c;
-    util_url_node_t *node = (util_url_node_t *)util_ald_alloc(sizeof(util_url_node_t));
+    util_url_node_t *node = (util_url_node_t *)util_ald_alloc(cache, sizeof(util_url_node_t));
 
     if (node) {
-        if (!(node->url = util_ald_strdup(n->url))) {
-            util_ald_free(node->url);
+        if (!(node->url = util_ald_strdup(cache, n->url))) {
+            util_ald_free(cache, node->url);
             return NULL;
         }
         node->search_cache = n->search_cache;
@@ -66,15 +67,15 @@ void *util_ldap_url_node_copy(void *c)
     }
 }
 
-void util_ldap_url_node_free(void *n)
+void util_ldap_url_node_free(util_ald_cache_t *cache, void *n)
 {
     util_url_node_t *node = (util_url_node_t *)n;
 
-    util_ald_free(node->url);
+    util_ald_free(cache, node->url);
     util_ald_destroy_cache(node->search_cache);
     util_ald_destroy_cache(node->compare_cache);
     util_ald_destroy_cache(node->dn_compare_cache);
-    util_ald_free(node);
+    util_ald_free(cache, node);
 }
 
 /* ------------------------------------------------------------------ */
@@ -92,10 +93,10 @@ int util_ldap_search_node_compare(void *a, void *b)
                  ((util_search_node_t *)b)->username) == 0);
 }
 
-void *util_ldap_search_node_copy(void *c)
+void *util_ldap_search_node_copy(util_ald_cache_t *cache, void *c)
 {
     util_search_node_t *node = (util_search_node_t *)c;
-    util_search_node_t *newnode = util_ald_alloc(sizeof(util_search_node_t));
+    util_search_node_t *newnode = util_ald_alloc(cache, sizeof(util_search_node_t));
 
     /* safety check */
     if (newnode) {
@@ -105,13 +106,13 @@ void *util_ldap_search_node_copy(void *c)
             int k = 0;
             int i = 0;
             while (node->vals[k++]);
-            if (!(newnode->vals = util_ald_alloc(sizeof(char *) * (k+1)))) {
-                util_ldap_search_node_free(newnode);
+            if (!(newnode->vals = util_ald_alloc(cache, sizeof(char *) * (k+1)))) {
+                util_ldap_search_node_free(cache, newnode);
                 return NULL;
             }
             while (node->vals[i]) {
-                if (!(newnode->vals[i] = util_ald_strdup(node->vals[i]))) {
-                    util_ldap_search_node_free(newnode);
+                if (!(newnode->vals[i] = util_ald_strdup(cache, node->vals[i]))) {
+                    util_ldap_search_node_free(cache, newnode);
                     return NULL;
                 }
                 i++;
@@ -120,10 +121,10 @@ void *util_ldap_search_node_copy(void *c)
         else {
             newnode->vals = NULL;
         }
-        if (!(newnode->username = util_ald_strdup(node->username)) ||
-            !(newnode->dn = util_ald_strdup(node->dn)) ||
-            !(newnode->bindpw = util_ald_strdup(node->bindpw)) ) {
-            util_ldap_search_node_free(newnode);
+        if (!(newnode->username = util_ald_strdup(cache, node->username)) ||
+            !(newnode->dn = util_ald_strdup(cache, node->dn)) ||
+            !(newnode->bindpw = util_ald_strdup(cache, node->bindpw)) ) {
+            util_ldap_search_node_free(cache, newnode);
             return NULL;
         }
         newnode->lastbind = node->lastbind;
@@ -132,20 +133,20 @@ void *util_ldap_search_node_copy(void *c)
     return (void *)newnode;
 }
 
-void util_ldap_search_node_free(void *n)
+void util_ldap_search_node_free(util_ald_cache_t *cache, void *n)
 {
     int i = 0;
     util_search_node_t *node = (util_search_node_t *)n;
     if (node->vals) {
         while (node->vals[i]) {
-            util_ald_free(node->vals[i++]);
+            util_ald_free(cache, node->vals[i++]);
         }
-        util_ald_free(node->vals);
+        util_ald_free(cache, node->vals);
     }
-    util_ald_free(node->username);
-    util_ald_free(node->dn);
-    util_ald_free(node->bindpw);
-    util_ald_free(node);
+    util_ald_free(cache, node->username);
+    util_ald_free(cache, node->dn);
+    util_ald_free(cache, node->bindpw);
+    util_ald_free(cache, node);
 }
 
 /* ------------------------------------------------------------------ */
@@ -165,16 +166,16 @@ int util_ldap_compare_node_compare(void *a, void *b)
            strcmp(na->value, nb->value) == 0);
 }
 
-void *util_ldap_compare_node_copy(void *c)
+void *util_ldap_compare_node_copy(util_ald_cache_t *cache, void *c)
 {
     util_compare_node_t *n = (util_compare_node_t *)c;
-    util_compare_node_t *node = (util_compare_node_t *)util_ald_alloc(sizeof(util_compare_node_t));
+    util_compare_node_t *node = (util_compare_node_t *)util_ald_alloc(cache, sizeof(util_compare_node_t));
 
     if (node) {
-        if (!(node->dn = util_ald_strdup(n->dn)) ||
-            !(node->attrib = util_ald_strdup(n->attrib)) ||
-            !(node->value = util_ald_strdup(n->value))) {
-            util_ldap_compare_node_free(node);
+        if (!(node->dn = util_ald_strdup(cache, n->dn)) ||
+            !(node->attrib = util_ald_strdup(cache, n->attrib)) ||
+            !(node->value = util_ald_strdup(cache, n->value))) {
+            util_ldap_compare_node_free(cache, node);
             return NULL;
         }
         node->lastcompare = n->lastcompare;
@@ -186,13 +187,13 @@ void *util_ldap_compare_node_copy(void *c)
     }
 }
 
-void util_ldap_compare_node_free(void *n)
+void util_ldap_compare_node_free(util_ald_cache_t *cache, void *n)
 {
     util_compare_node_t *node = (util_compare_node_t *)n;
-    util_ald_free(node->dn);
-    util_ald_free(node->attrib);
-    util_ald_free(node->value);
-    util_ald_free(node);
+    util_ald_free(cache, node->dn);
+    util_ald_free(cache, node->attrib);
+    util_ald_free(cache, node->value);
+    util_ald_free(cache, node);
 }
 
 /* ------------------------------------------------------------------ */
@@ -208,14 +209,14 @@ int util_ldap_dn_compare_node_compare(void *a, void *b)
                   ((util_dn_compare_node_t *)b)->reqdn) == 0);
 }
 
-void *util_ldap_dn_compare_node_copy(void *c)
+void *util_ldap_dn_compare_node_copy(util_ald_cache_t *cache, void *c)
 {
     util_dn_compare_node_t *n = (util_dn_compare_node_t *)c;
-    util_dn_compare_node_t *node = (util_dn_compare_node_t *)util_ald_alloc(sizeof(util_dn_compare_node_t));
+    util_dn_compare_node_t *node = (util_dn_compare_node_t *)util_ald_alloc(cache, sizeof(util_dn_compare_node_t));
     if (node) {
-        if (!(node->reqdn = util_ald_strdup(n->reqdn)) ||
-            !(node->dn = util_ald_strdup(n->dn))) {
-            util_ldap_dn_compare_node_free(node);
+        if (!(node->reqdn = util_ald_strdup(cache, n->reqdn)) ||
+            !(node->dn = util_ald_strdup(cache, n->dn))) {
+            util_ldap_dn_compare_node_free(cache, node);
             return NULL;
         }
         return node;
@@ -225,12 +226,12 @@ void *util_ldap_dn_compare_node_copy(void *c)
     }
 }
 
-void util_ldap_dn_compare_node_free(void *n)
+void util_ldap_dn_compare_node_free(util_ald_cache_t *cache, void *n)
 {
     util_dn_compare_node_t *node = (util_dn_compare_node_t *)n;
-    util_ald_free(node->reqdn);
-    util_ald_free(node->dn);
-    util_ald_free(node);
+    util_ald_free(cache, node->reqdn);
+    util_ald_free(cache, node->dn);
+    util_ald_free(cache, node);
 }
 
 
@@ -240,46 +241,53 @@ apr_status_t util_ldap_cache_module_kill(void *data);
 
 apr_status_t util_ldap_cache_module_kill(void *data)
 {
+    util_ldap_state_t *st = (util_ldap_state_t *)data;
+
 #if APR_HAS_SHARED_MEMORY
-    if (util_ldap_shm != NULL) {
-        apr_status_t result = apr_shm_destroy(util_ldap_shm);
-        util_ldap_shm = NULL;
+    if (st->cache_shm != NULL) {
+        apr_status_t result = apr_shm_destroy(st->cache_shm);
+        st->cache_shm = NULL;
+        apr_file_remove(st->cache_file, st->pool);
         return result;
     }
 #endif
-    util_ald_destroy_cache(util_ldap_cache);
+    util_ald_destroy_cache(st->util_ldap_cache);
     return APR_SUCCESS;
 }
 
-apr_status_t util_ldap_cache_init(apr_pool_t *pool, apr_size_t reqsize)
+apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st)
 {
 #if APR_HAS_SHARED_MEMORY
     apr_status_t result;
 
-    result = apr_shm_create(&util_ldap_shm, reqsize, MODLDAP_SHMEM_CACHE, pool);
+    if (!st->cache_file) {
+       return -1;
+    }
+
+    result = apr_shm_create(&st->cache_shm, st->cache_bytes, st->cache_file, st->pool);
     if (result == EEXIST) {
         /*
          * The cache could have already been created (i.e. we may be a child process).  See
          * if we can attach to the existing shared memory
          */
-        result = apr_shm_attach(&util_ldap_shm, MODLDAP_SHMEM_CACHE, pool);
+        result = apr_shm_attach(&st->cache_shm, st->cache_file, st->pool);
     } 
     if (result != APR_SUCCESS) {
         return result;
     }
 
     /* This will create a rmm "handler" to get into the shared memory area */
-    apr_rmm_init(&util_ldap_rmm, NULL,
-                       (void *)apr_shm_baseaddr_get(util_ldap_shm), reqsize, pool);
+    apr_rmm_init(&st->cache_rmm, NULL, (void *)apr_shm_baseaddr_get(st->cache_shm), st->cache_bytes, st->pool);
 #endif
 
-    apr_pool_cleanup_register(pool, NULL, util_ldap_cache_module_kill, apr_pool_cleanup_null);
+    apr_pool_cleanup_register(st->pool, st , util_ldap_cache_module_kill, apr_pool_cleanup_null);
 
-    util_ldap_cache = util_ald_create_cache(50,
-                                    util_ldap_url_node_hash,
-                                    util_ldap_url_node_compare,
-                                    util_ldap_url_node_copy,
-                                    util_ldap_url_node_free);
+    st->util_ldap_cache =
+        util_ald_create_cache(st,
+                              util_ldap_url_node_hash,
+                              util_ldap_url_node_compare,
+                              util_ldap_url_node_copy,
+                              util_ldap_url_node_free);
     return APR_SUCCESS;
 }
 
index 3fb680ef87cd7d83ef1de59038e9dc491a0cb974..2b16fcca6bd7c496e7e1fa79d72f6e698c0f7ef7 100644 (file)
  * LDAP Cache Manager
  */
 
+#if APR_HAS_SHARED_MEMORY
 #include <apr_shm.h>
 #include <apr_rmm.h> /* EDD */
+#endif
 
 typedef struct util_cache_node_t {
     void *payload;             /* Pointer to the payload */
@@ -37,47 +39,48 @@ typedef struct util_cache_node_t {
     struct util_cache_node_t *next;
 } util_cache_node_t;
 
-typedef struct util_ald_cache_t {
-    unsigned long size;                /* Size of cache array */
-    unsigned long maxentries;  /* Maximum number of cache entries */
-    unsigned long numentries;  /* Current number of cache entries */
-    unsigned long fullmark;    /* Used to keep track of when cache becomes 3/4 full */
-    apr_time_t marktime;       /* Time that the cache became 3/4 full */
-    unsigned long (*hash)(void *);  /* Func to hash the payload */
-    int (*compare)(void *, void *); /* Func to compare two payloads */
-    void * (*copy)(void *);    /* Func to alloc mem and copy payload to new mem */
-    void (*free)(void *);      /* Func to free mem used by the payload */
+typedef struct util_ald_cache util_ald_cache_t;
+
+struct util_ald_cache {
+    unsigned long size;                        /* Size of cache array */
+    unsigned long maxentries;           /* Maximum number of cache entries */
+    unsigned long numentries;           /* Current number of cache entries */
+    unsigned long fullmark;             /* Used to keep track of when cache becomes 3/4 full */
+    apr_time_t marktime;                /* Time that the cache became 3/4 full */
+    unsigned long (*hash)(void *);      /* Func to hash the payload */
+    int (*compare)(void *, void *);     /* Func to compare two payloads */
+    void * (*copy)(util_ald_cache_t *cache, void *); /* Func to alloc mem and copy payload to new mem */
+    void (*free)(util_ald_cache_t *cache, void *); /* Func to free mem used by the payload */
     util_cache_node_t **nodes;
 
-    unsigned long numpurges;   /* No. of times the cache has been purged */
-    double avg_purgetime;      /* Average time to purge the cache */
-    apr_time_t last_purge;     /* Time of the last purge */
-    unsigned long npurged;     /* Number of elements purged in last purge. This is not
-                                  obvious: it won't be 3/4 the size of the cache if 
-                                  there were a lot of expired entries. */
+    unsigned long numpurges;    /* No. of times the cache has been purged */
+    double avg_purgetime;       /* Average time to purge the cache */
+    apr_time_t last_purge;      /* Time of the last purge */
+    unsigned long npurged;      /* Number of elements purged in last purge. This is not
+                                   obvious: it won't be 3/4 the size of the cache if 
+                                   there were a lot of expired entries. */
 
-    unsigned long fetches;     /* Number of fetches */
-    unsigned long hits;                /* Number of cache hits */
-    unsigned long inserts;     /* Number of inserts */
-    unsigned long removes;     /* Number of removes */
-} util_ald_cache_t;
+    unsigned long fetches;      /* Number of fetches */
+    unsigned long hits;         /* Number of cache hits */
+    unsigned long inserts;      /* Number of inserts */
+    unsigned long removes;      /* Number of removes */
 
 #if APR_HAS_SHARED_MEMORY
-apr_shm_t *util_ldap_shm;
-apr_rmm_t *util_ldap_rmm;
+    apr_shm_t *shm_addr;
+    apr_rmm_t *rmm_addr;
 #endif
-util_ald_cache_t *util_ldap_cache;
+
+};
 
 #if APR_HAS_THREADS
-apr_thread_rwlock_t *util_ldap_cache_lock;
 #define LDAP_CACHE_LOCK_CREATE(p) \
-    if (!util_ldap_cache_lock) apr_thread_rwlock_create(&util_ldap_cache_lock, p)
+    if (!st->util_ldap_cache_lock) apr_thread_rwlock_create(&st->util_ldap_cache_lock, st->pool)
 #define LDAP_CACHE_WRLOCK() \
-    apr_thread_rwlock_wrlock(util_ldap_cache_lock)
+    apr_thread_rwlock_wrlock(st->util_ldap_cache_lock)
 #define LDAP_CACHE_UNLOCK() \
-    apr_thread_rwlock_unlock(util_ldap_cache_lock)
+    apr_thread_rwlock_unlock(st->util_ldap_cache_lock)
 #define LDAP_CACHE_RDLOCK() \
-    apr_thread_rwlock_rdlock(util_ldap_cache_lock)
+    apr_thread_rwlock_rdlock(st->util_ldap_cache_lock)
 #else
 #define LDAP_CACHE_LOCK_CREATE(p)
 #define LDAP_CACHE_WRLOCK()
@@ -152,35 +155,39 @@ typedef struct util_dn_compare_node_t {
 /* util_ldap_cache.c */
 unsigned long util_ldap_url_node_hash(void *n);
 int util_ldap_url_node_compare(void *a, void *b);
-void *util_ldap_url_node_copy(void *c);
-void util_ldap_url_node_free(void *n);
+void *util_ldap_url_node_copy(util_ald_cache_t *cache, void *c);
+void util_ldap_url_node_free(util_ald_cache_t *cache, void *n);
 unsigned long util_ldap_search_node_hash(void *n);
 int util_ldap_search_node_compare(void *a, void *b);
-void *util_ldap_search_node_copy(void *c);
-void util_ldap_search_node_free(void *n);
+void *util_ldap_search_node_copy(util_ald_cache_t *cache, void *c);
+void util_ldap_search_node_free(util_ald_cache_t *cache, void *n);
 unsigned long util_ldap_compare_node_hash(void *n);
 int util_ldap_compare_node_compare(void *a, void *b);
-void *util_ldap_compare_node_copy(void *c);
-void util_ldap_compare_node_free(void *n);
+void *util_ldap_compare_node_copy(util_ald_cache_t *cache, void *c);
+void util_ldap_compare_node_free(util_ald_cache_t *cache, void *n);
 unsigned long util_ldap_dn_compare_node_hash(void *n);
 int util_ldap_dn_compare_node_compare(void *a, void *b);
-void *util_ldap_dn_compare_node_copy(void *c);
-void util_ldap_dn_compare_node_free(void *n);
+void *util_ldap_dn_compare_node_copy(util_ald_cache_t *cache, void *c);
+void util_ldap_dn_compare_node_free(util_ald_cache_t *cache, void *n);
 
 
 /* util_ldap_cache_mgr.c */
 
-void util_ald_free(const void *ptr);
-void *util_ald_alloc(unsigned long size);
-const char *util_ald_strdup(const char *s);
+/* Cache alloc and free function, dealing or not with shm */
+void util_ald_free(util_ald_cache_t *cache, const void *ptr);
+void *util_ald_alloc(util_ald_cache_t *cache, unsigned long size);
+const char *util_ald_strdup(util_ald_cache_t *cache, const char *s);
+
+/* Cache managing function */
 unsigned long util_ald_hash_string(int nstr, ...);
 void util_ald_cache_purge(util_ald_cache_t *cache);
 util_url_node_t *util_ald_create_caches(util_ldap_state_t *s, const char *url);
-util_ald_cache_t *util_ald_create_cache(unsigned long maxentries,
+util_ald_cache_t *util_ald_create_cache(util_ldap_state_t *st,
                                 unsigned long (*hashfunc)(void *), 
                                 int (*comparefunc)(void *, void *),
-                                void * (*copyfunc)(void *),
-                                void (*freefunc)(void *));
+                                void * (*copyfunc)(util_ald_cache_t *cache, void *),
+                                void (*freefunc)(util_ald_cache_t *cache, void *));
+                                
 void util_ald_destroy_cache(util_ald_cache_t *cache);
 void *util_ald_cache_fetch(util_ald_cache_t *cache, void *payload);
 void util_ald_cache_insert(util_ald_cache_t *cache, void *payload);
index a8f794ef8929a520bbd4c398ef861b8fc49d3e5c..3706514e1503179310a733c6138f0493121e904f 100644 (file)
@@ -73,14 +73,17 @@ static const unsigned long primes[] =
   0
 };
 
-void util_ald_free(const void *ptr)
+void util_ald_free(util_ald_cache_t *cache, const void *ptr)
 {
 #if APR_HAS_SHARED_MEMORY
-    if (util_ldap_shm) {
+    if (cache->rmm_addr) {
         if (ptr)
-            apr_rmm_free(util_ldap_rmm, apr_rmm_offset_get(util_ldap_rmm, (void *)ptr));
-    } else {
+            /* Free in shared memory */
+            apr_rmm_free(cache->rmm_addr, apr_rmm_offset_get(cache->rmm_addr, (void *)ptr));
+    }
+    else {
         if (ptr)
+            /* Cache shm is not used */
             free((void *)ptr);
     }
 #else
@@ -89,14 +92,17 @@ void util_ald_free(const void *ptr)
 #endif
 }
 
-void *util_ald_alloc(unsigned long size)
+void *util_ald_alloc(util_ald_cache_t *cache, unsigned long size)
 {
     if (0 == size)
         return NULL;
 #if APR_HAS_SHARED_MEMORY
-    if (util_ldap_shm) {
-        return (void *)apr_rmm_addr_get(util_ldap_rmm, apr_rmm_calloc(util_ldap_rmm, size));
-    } else {
+    if (cache->rmm_addr) {
+        /* allocate from shared memory */
+        return (void *)apr_rmm_addr_get(cache->rmm_addr, apr_rmm_calloc(cache->rmm_addr, size));
+    }
+    else {
+        /* Cache shm is not used */
         return (void *)calloc(sizeof(char), size);
     }
 #else
@@ -104,11 +110,12 @@ void *util_ald_alloc(unsigned long size)
 #endif
 }
 
-const char *util_ald_strdup(const char *s)
+const char *util_ald_strdup(util_ald_cache_t *cache, const char *s)
 {
 #if APR_HAS_SHARED_MEMORY
-    if (util_ldap_shm) {
-        char *buf = (char *)apr_rmm_addr_get(util_ldap_rmm, apr_rmm_calloc(util_ldap_rmm, strlen(s)+1));
+    if (cache->rmm_addr) {
+        /* allocate from shared memory */
+        char *buf = (char *)apr_rmm_addr_get(cache->rmm_addr, apr_rmm_calloc(cache->rmm_addr, strlen(s)+1));
         if (buf) {
             strcpy(buf, s);
             return buf;
@@ -117,6 +124,7 @@ const char *util_ald_strdup(const char *s)
             return NULL;
         }
     } else {
+        /* Cache shm is not used */
         return strdup(s);
     }
 #else
@@ -178,8 +186,8 @@ void util_ald_cache_purge(util_ald_cache_t *cache)
         while (p != NULL) {
             if (p->add_time < cache->marktime) {
                q = p->next;
-               (*cache->free)(p->payload);
-               util_ald_free(p);
+               (*cache->free)(cache, p->payload);
+               util_ald_free(cache, p);
                cache->numentries--;
                cache->npurged++;
                p = q;
@@ -208,17 +216,17 @@ util_url_node_t *util_ald_create_caches(util_ldap_state_t *st, const char *url)
     util_ald_cache_t *dn_compare_cache;
 
     /* create the three caches */
-    search_cache = util_ald_create_cache(st->search_cache_size,
+    search_cache = util_ald_create_cache(st,
                                          util_ldap_search_node_hash,
                                          util_ldap_search_node_compare,
                                          util_ldap_search_node_copy,
                                          util_ldap_search_node_free);
-    compare_cache = util_ald_create_cache(st->compare_cache_size,
+    compare_cache = util_ald_create_cache(st,
                                           util_ldap_compare_node_hash,
                                           util_ldap_compare_node_compare,
                                           util_ldap_compare_node_copy,
                                           util_ldap_compare_node_free);
-    dn_compare_cache = util_ald_create_cache(st->compare_cache_size,
+    dn_compare_cache = util_ald_create_cache(st,
                                              util_ldap_dn_compare_node_hash,
                                              util_ldap_dn_compare_node_compare,
                                              util_ldap_dn_compare_node_copy,
@@ -233,7 +241,7 @@ util_url_node_t *util_ald_create_caches(util_ldap_state_t *st, const char *url)
         curl->compare_cache = compare_cache;
         curl->dn_compare_cache = dn_compare_cache;
 
-        util_ald_cache_insert(util_ldap_cache, curl);
+        util_ald_cache_insert(st->util_ldap_cache, curl);
 
     }
 
@@ -241,32 +249,36 @@ util_url_node_t *util_ald_create_caches(util_ldap_state_t *st, const char *url)
 }
 
 
-util_ald_cache_t *util_ald_create_cache(unsigned long maxentries,
+util_ald_cache_t *util_ald_create_cache(util_ldap_state_t *st,
                                 unsigned long (*hashfunc)(void *), 
                                 int (*comparefunc)(void *, void *),
-                                void * (*copyfunc)(void *),
-                                void (*freefunc)(void *))
+                                void * (*copyfunc)(util_ald_cache_t *cache, void *),
+                                void (*freefunc)(util_ald_cache_t *cache, void *))
 {
     util_ald_cache_t *cache;
     unsigned long i;
 
-    if (maxentries <= 0)
+    if (st->search_cache_size <= 0)
         return NULL;
 
-    cache = (util_ald_cache_t *)util_ald_alloc(sizeof(util_ald_cache_t));
+#if APR_HAS_SHARED_MEMORY
+    cache = (util_ald_cache_t *)apr_rmm_addr_get(st->cache_rmm, apr_rmm_calloc(st->cache_rmm, sizeof(util_ald_cache_t)));
+#else
+    cache = (util_ald_cache_t *)calloc(sizeof(util_ald_cache_t), 1);
+#endif
     if (!cache)
         return NULL;
 
-    cache->maxentries = maxentries;
+    cache->maxentries = st->search_cache_size;
     cache->numentries = 0;
-    cache->size = maxentries / 3;
+    cache->size = st->search_cache_size / 3;
     if (cache->size < 64) cache->size = 64;
         for (i = 0; primes[i] && primes[i] < cache->size; ++i) ;
             cache->size = primes[i]? primes[i] : primes[i-1];
 
-    cache->nodes = (util_cache_node_t **)util_ald_alloc(cache->size * sizeof(util_cache_node_t *));
+    cache->nodes = (util_cache_node_t **)util_ald_alloc(cache, cache->size * sizeof(util_cache_node_t *));
     if (!cache->nodes) {
-        util_ald_free(cache);
+        util_ald_free(cache, cache);
         return NULL;
     }
 
@@ -306,13 +318,13 @@ void util_ald_destroy_cache(util_ald_cache_t *cache)
         q = NULL;
         while (p != NULL) {
             q = p->next;
-           (*cache->free)(p->payload);
-           util_ald_free(p);
+           (*cache->free)(cache, p->payload);
+           util_ald_free(cache, p);
            p = q;
         }
     }
-    util_ald_free(cache->nodes);
-    util_ald_free(cache);
+    util_ald_free(cache, cache->nodes);
+    util_ald_free(cache, cache);
 }
 
 void *util_ald_cache_fetch(util_ald_cache_t *cache, void *payload)
@@ -351,11 +363,13 @@ void util_ald_cache_insert(util_ald_cache_t *cache, void *payload)
     if (cache == NULL || payload == NULL)
         return;
 
+    if ((node = (util_cache_node_t *)util_ald_alloc(cache, sizeof(util_cache_node_t))) == NULL)
+        return;
+
     cache->inserts++;
     hashval = (*cache->hash)(payload) % cache->size;
-    node = (util_cache_node_t *)util_ald_alloc(sizeof(util_cache_node_t));
     node->add_time = apr_time_now();
-    node->payload = (*cache->copy)(payload);
+    node->payload = (*cache->copy)(cache, payload);
     node->next = cache->nodes[hashval];
     cache->nodes[hashval] = node;
     if (++cache->numentries == cache->fullmark) 
@@ -392,8 +406,8 @@ void util_ald_cache_remove(util_ald_cache_t *cache, void *payload)
         /* We found the node and it's not the first in the list */
         q->next = p->next;
     }
-    (*cache->free)(p->payload);
-    util_ald_free(p);
+    (*cache->free)(cache, p->payload);
+    util_ald_free(cache, p);
     cache->numentries--;
 }
 
@@ -460,16 +474,19 @@ char *util_ald_cache_display_stats(apr_pool_t *p, util_ald_cache_t *cache, char
     return buf;
 }
 
-char *util_ald_cache_display(apr_pool_t *pool)
+char *util_ald_cache_display(apr_pool_t *pool, util_ldap_state_t *st)
 {
     unsigned long i;
     char *buf, *t1, *t2, *t3;
 
+    util_ald_cache_t *util_ldap_cache = st->util_ldap_cache;
+
+
     if (!util_ldap_cache) {
         return "<tr valign='top'><td nowrap colspan=7>Cache has not been enabled/initialised.</td></tr>";
     }
 
-    buf = util_ald_cache_display_stats(pool, util_ldap_cache, "LDAP URL Cache");
+    buf = util_ald_cache_display_stats(pool, st->util_ldap_cache, "LDAP URL Cache");
 
     for (i=0; i < util_ldap_cache->size; ++i) {
         util_cache_node_t *p;