diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-05-22 22:27:25 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-05-22 22:27:25 +0000 |
commit | 25c3deff41adc496a1e317364d951997b7b0e2b3 (patch) | |
tree | 201bc8703c1769ff795b32835fe597936d191471 /lib/gnutls_db.c | |
parent | 949d62928648b316acbcb0043dc530624060e530 (diff) | |
download | gnutls-25c3deff41adc496a1e317364d951997b7b0e2b3.tar.gz |
cleanups and several fixes(and speedups) in the resume DB
Diffstat (limited to 'lib/gnutls_db.c')
-rw-r--r-- | lib/gnutls_db.c | 95 |
1 files changed, 69 insertions, 26 deletions
diff --git a/lib/gnutls_db.c b/lib/gnutls_db.c index 6e1545e031..10cf405521 100644 --- a/lib/gnutls_db.c +++ b/lib/gnutls_db.c @@ -18,12 +18,21 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +/* This file contains functions that manipulate a database + * for resumed sessions. + */ #include <defines.h> #include "gnutls_int.h" #include "gnutls_errors.h" #include "gnutls_session.h" +#include "debug.h" + #ifdef HAVE_LIBGDBM -#include <gdbm.h> +# define GNUTLS_DBF state->gnutls_internals.db_reader +# define GNUTLS_DBNAME state->gnutls_internals.db_name +# define REOPEN_DB() if (GNUTLS_DBF!=NULL) \ + gdbm_close( GNUTLS_DBF); \ + GNUTLS_DBF = gdbm_open(GNUTLS_DBNAME, 0, GDBM_READER, 0600, NULL); #endif int gnutls_set_cache_expiration( GNUTLS_STATE state, int seconds) { @@ -31,12 +40,32 @@ int gnutls_set_cache_expiration( GNUTLS_STATE state, int seconds) { return 0; } +/* creates the database specified by filename, + * and opens it for reading. + */ int gnutls_set_db_name( GNUTLS_STATE state, char* filename) { #ifdef HAVE_LIBGDBM +GDBM_FILE dbf; - if (state->gnutls_internals.db_name!=NULL) - gnutls_free(state->gnutls_internals.db_name); - state->gnutls_internals.db_name = strdup(filename); + if (filename==NULL) return 0; + + /* deallocate previous name */ + if (GNUTLS_DBNAME!=NULL) + gnutls_free(GNUTLS_DBNAME); + + /* set name */ + GNUTLS_DBNAME = strdup(filename); + if (GNUTLS_DBNAME==NULL) return GNUTLS_E_MEMORY_ERROR; + + /* create if it does not exist + */ + dbf = gdbm_open( filename, 0, GDBM_WRCREAT, 0600, NULL); + if (dbf==NULL) return GNUTLS_E_DB_ERROR; + gdbm_close(dbf); + + /* open for reader */ + GNUTLS_DBF = gdbm_open(GNUTLS_DBNAME, 0, GDBM_READER, 0600, NULL); + if (GNUTLS_DBF==NULL) return GNUTLS_E_DB_ERROR; return 0; #else @@ -44,13 +73,18 @@ int gnutls_set_db_name( GNUTLS_STATE state, char* filename) { #endif } + +/* This function removes expired and invalid sessions from the + * database + */ int gnutls_clean_db( GNUTLS_STATE state) { #ifdef HAVE_LIBGDBM GDBM_FILE dbf; +int ret; datum key; time_t timestamp; - dbf = gdbm_open(state->gnutls_internals.db_name, 0, GDBM_WRCREAT, 0600, NULL); + dbf = gdbm_open(GNUTLS_DBNAME, 0, GDBM_WRITER, 0600, NULL); if (dbf==NULL) return GNUTLS_E_AGAIN; key = gdbm_firstkey(dbf); @@ -66,8 +100,13 @@ time_t timestamp; free(key.dptr); key = gdbm_nextkey(dbf, key); } + ret = gdbm_reorganize(dbf); + gdbm_close(dbf); - + REOPEN_DB(); + + if (ret!=0) return GNUTLS_E_DB_ERROR; + return 0; #else return GNUTLS_E_UNIMPLEMENTED_FEATURE; @@ -83,55 +122,59 @@ datum key = { state->security_parameters.session_id, state->security_parameters. datum content; int ret = 0; - if (state->gnutls_internals.resumable==RESUME_FALSE) { + if (state->gnutls_internals.resumable==RESUME_FALSE) return GNUTLS_E_INVALID_SESSION; - } - if (state->gnutls_internals.db_name==NULL) { + + if (GNUTLS_DBNAME==NULL) return GNUTLS_E_DB_ERROR; - } - if (state->security_parameters.session_id==NULL || state->security_parameters.session_id_size==0) { + + if (state->security_parameters.session_id==NULL || state->security_parameters.session_id_size==0) return GNUTLS_E_INVALID_SESSION; - } + /* allocate space for data */ - content.dptr = gnutls_malloc( sizeof(SecurityParameters) + state->gnutls_key->auth_info_size ); content.dsize = sizeof(SecurityParameters) + state->gnutls_key->auth_info_size; + content.dptr = gnutls_malloc( content.dsize); + if (content.dptr==NULL) return GNUTLS_E_MEMORY_ERROR; /* copy data */ memcpy( content.dptr, (void*)&state->security_parameters, sizeof(SecurityParameters)); memcpy( &content.dptr[sizeof(SecurityParameters)], state->gnutls_key->auth_info, state->gnutls_key->auth_info_size); - dbf = gdbm_open(state->gnutls_internals.db_name, 0, GDBM_WRCREAT|GDBM_FAST, 0600, NULL); - if (dbf==NULL) return GNUTLS_E_AGAIN; + dbf = gdbm_open(GNUTLS_DBNAME, 0, GDBM_WRITER, 0600, NULL); + if (dbf==NULL) { + gnutls_free(content.dptr); + /* cannot open db for writing. This may happen if multiple + * instances try to write. + */ + return GNUTLS_E_AGAIN; + } ret = gdbm_store( dbf, key, content, GDBM_INSERT); gnutls_free( content.dptr); gdbm_close(dbf); - return (ret == 0 ? ret : GNUTLS_E_UNKNOWN_ERROR); #else return GNUTLS_E_UNIMPLEMENTED_FEATURE; #endif } - int _gnutls_server_restore_session( GNUTLS_STATE state, uint8* session_id, int session_id_size) { #ifdef HAVE_LIBGDBM -GDBM_FILE dbf; datum content; datum key = { session_id, session_id_size}; int ret; - if (state->gnutls_internals.db_name==NULL) return GNUTLS_E_DB_ERROR; + if (GNUTLS_DBNAME==NULL) return GNUTLS_E_DB_ERROR; - dbf = gdbm_open(state->gnutls_internals.db_name, 0, GDBM_READER|GDBM_FAST, 0600, NULL); - if (dbf==NULL) return GNUTLS_E_AGAIN; - content = gdbm_fetch( dbf, key); - gdbm_close(dbf); + if (GNUTLS_DBF==NULL) return GNUTLS_E_DB_ERROR; + content = gdbm_fetch( GNUTLS_DBF, key); - if (content.dptr==NULL) return GNUTLS_E_INVALID_SESSION; + if (content.dptr==NULL) { + return GNUTLS_E_INVALID_SESSION; + } /* expiration check is performed inside */ ret = gnutls_set_current_session( state, content.dptr, content.dsize); @@ -150,9 +193,9 @@ GDBM_FILE dbf; datum key = { session_id, session_id_size}; int ret; - if (state->gnutls_internals.db_name==NULL) return GNUTLS_E_DB_ERROR; + if (GNUTLS_DBNAME==NULL) return GNUTLS_E_DB_ERROR; - dbf = gdbm_open(state->gnutls_internals.db_name, 0, GDBM_READER|GDBM_FAST, 0600, NULL); + dbf = gdbm_open(GNUTLS_DBNAME, 0, GDBM_READER, 0600, NULL); if (dbf==NULL) return GNUTLS_E_AGAIN; ret = gdbm_delete( dbf, key); gdbm_close(dbf); |