summaryrefslogtreecommitdiff
path: root/lib/gnutls_db.c
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-05-22 22:27:25 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-05-22 22:27:25 +0000
commit25c3deff41adc496a1e317364d951997b7b0e2b3 (patch)
tree201bc8703c1769ff795b32835fe597936d191471 /lib/gnutls_db.c
parent949d62928648b316acbcb0043dc530624060e530 (diff)
downloadgnutls-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.c95
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);