Introduce dynamic memory pool for sessions
This pool has a fixed size and the aim is to avoid arbitrary limits on entry's components, while maintaining an overall fixed entry size. Accessors function for a storage unit are provided for future use. Signed-off-by: Simo Sorce <simo@redhat.com> git-svn-id: https://modmellon.googlecode.com/svn/trunk@231 a716ebb1-153a-0410-b759-cfb97c6a1b53
This commit is contained in:
parent
66f6d2cb08
commit
8dacb03887
7
README
7
README
|
@ -97,6 +97,13 @@ for mod_auth_mellon. The following is an example configuration:
|
|||
# Default: MellonCacheSize 100
|
||||
MellonCacheSize 100
|
||||
|
||||
# MellonCacheEntrySize sets the maximum size for a single session entry in
|
||||
# bytes. When mod_auth_mellon reaches this limit, it cannot store any more
|
||||
# data in the session and will return an error. The minimum entry size is
|
||||
# 65536 bytes, values lower than that will be ignored and the minimum will
|
||||
# be used.
|
||||
# Default: MellonCacheEntrySize 196608
|
||||
|
||||
# MellonLockFile is the full path to a file used for synchronizing access
|
||||
# to the session data. The path should only be used by one instance of
|
||||
# apache at a time. The server must be restarted before any changes to this
|
||||
|
|
|
@ -78,6 +78,8 @@
|
|||
#define AM_CACHE_MAX_LASSO_IDENTITY_SIZE 1024
|
||||
#define AM_CACHE_MAX_LASSO_SESSION_SIZE 32768
|
||||
#define AM_CACHE_MAX_LASSO_SAML_RESPONSE_SIZE 65536
|
||||
#define AM_CACHE_DEFAULT_ENTRY_SIZE 196608
|
||||
#define AM_CACHE_MIN_ENTRY_SIZE 65536
|
||||
|
||||
|
||||
/* This is the length of the id we use (for session IDs and
|
||||
|
@ -101,12 +103,15 @@ typedef struct am_mod_cfg_rec {
|
|||
int post_count;
|
||||
apr_size_t post_size;
|
||||
|
||||
int entry_size;
|
||||
|
||||
/* These variables can't be allowed to change after the session store
|
||||
* has been initialized. Therefore we copy them before initializing
|
||||
* the session store.
|
||||
*/
|
||||
int init_cache_size;
|
||||
const char *init_lock_file;
|
||||
apr_size_t init_entry_size;
|
||||
|
||||
apr_shm_t *cache;
|
||||
apr_global_mutex_t *lock;
|
||||
|
@ -240,6 +245,9 @@ typedef struct am_dir_cfg_rec {
|
|||
LassoServer *server;
|
||||
} am_dir_cfg_rec;
|
||||
|
||||
typedef struct am_cache_storage_t {
|
||||
apr_uintptr_t ptr;
|
||||
} am_cache_storage_t;
|
||||
|
||||
typedef struct am_cache_env_t {
|
||||
char varname[AM_CACHE_VARSIZE];
|
||||
|
@ -262,6 +270,10 @@ typedef struct am_cache_entry_t {
|
|||
char lasso_saml_response[AM_CACHE_MAX_LASSO_SAML_RESPONSE_SIZE];
|
||||
|
||||
am_cache_env_t env[AM_CACHE_ENVSIZE];
|
||||
|
||||
apr_size_t pool_size;
|
||||
apr_size_t pool_used;
|
||||
char pool[];
|
||||
} am_cache_entry_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -322,6 +334,8 @@ void am_cookie_delete(request_rec *r);
|
|||
|
||||
am_cache_entry_t *am_cache_lock(server_rec *s,
|
||||
am_cache_key_t type, const char *key);
|
||||
const char *am_cache_entry_get_string(am_cache_entry_t *e,
|
||||
am_cache_storage_t *slot);
|
||||
am_cache_entry_t *am_cache_new(server_rec *s, const char *key);
|
||||
void am_cache_unlock(server_rec *s, am_cache_entry_t *entry);
|
||||
|
||||
|
|
|
@ -113,6 +113,96 @@ am_cache_entry_t *am_cache_lock(server_rec *s,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline void am_cache_storage_null(am_cache_storage_t *slot)
|
||||
{
|
||||
slot->ptr = 0;
|
||||
}
|
||||
|
||||
static inline apr_size_t am_cache_entry_pool_left(am_cache_entry_t *e)
|
||||
{
|
||||
return e->pool_size - e->pool_used;
|
||||
}
|
||||
|
||||
static inline apr_size_t am_cache_entry_pool_size(am_mod_cfg_rec *cfg)
|
||||
{
|
||||
return cfg->init_entry_size - sizeof(am_cache_entry_t);
|
||||
}
|
||||
|
||||
/* This function sets a string into the specified storage on the entry.
|
||||
*
|
||||
* NOTE: The string pointer may be NULL, in that case storage is freed
|
||||
* and set to NULL.
|
||||
*
|
||||
* Parametrs:
|
||||
* am_cache_entry_t *entry Pointer to an entry
|
||||
* am_cache_storage_t *slot Pointer to storage
|
||||
* const char *string Pointer to a replacement string
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, HTTP_INTERNAL_SERVER_ERROR on error.
|
||||
*/
|
||||
static int am_cache_entry_store_string(am_cache_entry_t *entry,
|
||||
am_cache_storage_t *slot,
|
||||
const char *string)
|
||||
{
|
||||
char *datastr = NULL;
|
||||
apr_size_t datalen = 0;
|
||||
apr_size_t str_len = 0;
|
||||
|
||||
if (string == NULL) return 0;
|
||||
|
||||
if (slot->ptr != 0) {
|
||||
datastr = &entry->pool[slot->ptr];
|
||||
datalen = strlen(datastr) + 1;
|
||||
}
|
||||
str_len = strlen(string) + 1;
|
||||
if (str_len - datalen <= 0) {
|
||||
memcpy(datastr, string, str_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* recover space if slot happens to point to the last allocated space */
|
||||
if (slot->ptr + datalen == entry->pool_used) {
|
||||
entry->pool_used -= datalen;
|
||||
slot->ptr = 0;
|
||||
}
|
||||
|
||||
if (am_cache_entry_pool_left(entry) < str_len) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
|
||||
"apr_cache_entry_store_string() asked %zd available: %zd. "
|
||||
"It may be a good idea to increase MellonCacheEntrySize.",
|
||||
str_len, am_cache_entry_pool_left(entry));
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
slot->ptr = entry->pool_used;
|
||||
datastr = &entry->pool[slot->ptr];
|
||||
memcpy(datastr, string, str_len);
|
||||
entry->pool_used += str_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the string in the storage slot specified
|
||||
*
|
||||
*
|
||||
* Parametrs:
|
||||
* am_cache_entry_t *entry Pointer to an entry
|
||||
* am_cache_storage_t *slot Pointer to storage slot
|
||||
*
|
||||
* Returns:
|
||||
* A string or NULL if the slot is empty.
|
||||
*/
|
||||
const char *am_cache_entry_get_string(am_cache_entry_t *e,
|
||||
am_cache_storage_t *slot)
|
||||
{
|
||||
char *ret = NULL;
|
||||
|
||||
if (slot->ptr != 0) {
|
||||
ret = &e->pool[slot->ptr];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This function locks the session table and creates a new session entry.
|
||||
* It will first attempt to locate a free session. If it doesn't find a
|
||||
|
@ -227,6 +317,10 @@ am_cache_entry_t *am_cache_new(server_rec *s, const char *key)
|
|||
t->lasso_identity[0] = '\0';
|
||||
t->lasso_session[0] = '\0';
|
||||
|
||||
t->pool_size = am_cache_entry_pool_size(mod_cfg);
|
||||
t->pool[0] = '\0';
|
||||
t->pool_used = 1;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
|
|
@ -862,6 +862,15 @@ const command_rec auth_mellon_commands[] = {
|
|||
" restart the server before any changes to this directive will"
|
||||
" take effect. The default value is 100."
|
||||
),
|
||||
AP_INIT_TAKE1(
|
||||
"MellonCacheEntrySize",
|
||||
am_set_module_config_int_slot,
|
||||
(void *)APR_OFFSETOF(am_mod_cfg_rec, entry_size),
|
||||
RSRC_CONF,
|
||||
"The maximum size for a single session entry. You must"
|
||||
" restart the server before any changes to this directive will"
|
||||
" take effect. The default value is 192KiB."
|
||||
),
|
||||
AP_INIT_TAKE1(
|
||||
"MellonLockFile",
|
||||
am_set_module_config_file_slot,
|
||||
|
@ -1571,8 +1580,11 @@ void *auth_mellon_server_config(apr_pool_t *p, server_rec *s)
|
|||
mod->post_count = post_count;
|
||||
mod->post_size = post_size;
|
||||
|
||||
mod->entry_size = AM_CACHE_DEFAULT_ENTRY_SIZE;
|
||||
|
||||
mod->init_cache_size = 0;
|
||||
mod->init_lock_file = NULL;
|
||||
mod->init_entry_size = 0;
|
||||
|
||||
mod->cache = NULL;
|
||||
mod->lock = NULL;
|
||||
|
|
|
@ -88,9 +88,13 @@ static int am_global_init(apr_pool_t *conf, apr_pool_t *log,
|
|||
*/
|
||||
mod->init_cache_size = mod->cache_size;
|
||||
mod->init_lock_file = apr_pstrdup(conf, mod->lock_file);
|
||||
mod->init_entry_size = mod->entry_size;
|
||||
if (mod->init_entry_size < AM_CACHE_MIN_ENTRY_SIZE) {
|
||||
mod->init_entry_size = AM_CACHE_MIN_ENTRY_SIZE;
|
||||
}
|
||||
|
||||
/* find out the memory size of the cache */
|
||||
mem_size = sizeof(am_cache_entry_t) * mod->init_cache_size;
|
||||
mem_size = mod->init_entry_size * mod->init_cache_size;
|
||||
|
||||
|
||||
/* Create the shared memory, exit if it fails. */
|
||||
|
|
Loading…
Reference in New Issue