summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
-rw-r--r--NEWS8
-rw-r--r--src/gnutls_cache.c118
-rw-r--r--src/gnutls_config.c7
3 files changed, 59 insertions, 74 deletions
diff --git a/NEWS b/NEWS
index 7b796f0..88f4496 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,10 @@
1** Version 0.5.7 1** Version 0.5.7
2- Force usage of SDBM. For some reason the default in
3 my system had issues after reaching a limit of entries.
4 SDBM seems stable so force it.
5
6- Optimizations in session caching.
7
2- Added support for session tickets. This allows a 8- Added support for session tickets. This allows a
3 server to avoid using a session cache and still support 9 server to avoid using a session cache and still support
4 session resumption. This is at the cost of transporting 10 session resumption. This is at the cost of transporting
@@ -7,8 +13,6 @@
7- Depend on gnutls 2.10.0 to force support for safe 13- Depend on gnutls 2.10.0 to force support for safe
8 renegotiation. 14 renegotiation.
9 15
10- Optimizations in session caching.
11
12** Version 0.5.6 (2010-03-24) 16** Version 0.5.6 (2010-03-24)
13- Corrected issue with firefox and long POST data (by 17- Corrected issue with firefox and long POST data (by
14 handling EINTR and EAGAIN errors in read). 18 handling EINTR and EAGAIN errors in read).
diff --git a/src/gnutls_cache.c b/src/gnutls_cache.c
index 4d0a733..3ca8cb5 100644
--- a/src/gnutls_cache.c
+++ b/src/gnutls_cache.c
@@ -33,6 +33,9 @@
33#include "unixd.h" 33#include "unixd.h"
34#endif 34#endif
35 35
36/* it seems the default has some strange errors. Use SDBM
37 */
38#define ODB "SDBM"
36 39
37#define MC_TAG "mod_gnutls:" 40#define MC_TAG "mod_gnutls:"
38#define MC_TAG_LEN sizeof(MC_TAG) 41#define MC_TAG_LEN sizeof(MC_TAG)
@@ -295,92 +298,68 @@ static int mc_cache_delete(void* baton, gnutls_datum_t key)
295 298
296#define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD ) 299#define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD )
297 300
298static int dbm_cache_expire(mgs_handle_t *ctxt) 301static void dbm_cache_expire(mgs_handle_t *ctxt)
299{ 302{
300 apr_status_t rv; 303 apr_status_t rv;
301 apr_dbm_t *dbm; 304 apr_dbm_t *dbm;
302 apr_datum_t *keylist;
303 apr_datum_t dbmkey; 305 apr_datum_t dbmkey;
304 apr_datum_t dbmval; 306 apr_datum_t dbmval;
305 apr_time_t ex; 307 apr_time_t now;
306 apr_time_t dtime; 308 apr_time_t dtime;
307 apr_pool_t* spool; 309 apr_pool_t* spool;
308 int i = 0; 310 int total, deleted;
309 int keyidx = 0;
310 int should_delete = 0;
311
312 ex = apr_time_now();
313 311
314 if (ex - ctxt->sc->last_cache_check < 900) 312 now = apr_time_now();
315 return 0; 313
314 if (now - ctxt->sc->last_cache_check < (ctxt->sc->cache_timeout)/2)
315 return;
316 316
317 ctxt->sc->last_cache_check = ex; 317 ctxt->sc->last_cache_check = now;
318 318
319 apr_pool_create(&spool, ctxt->c->pool); 319 apr_pool_create(&spool, ctxt->c->pool);
320 320
321 rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, APR_DBM_READONLY, 321 total = 0;
322 deleted = 0;
323
324 rv = apr_dbm_open_ex(&dbm, ODB, ctxt->sc->cache_config, APR_DBM_RWCREATE,
322 SSL_DBM_FILE_MODE, spool); 325 SSL_DBM_FILE_MODE, spool);
323 if (rv != APR_SUCCESS) { 326 if (rv != APR_SUCCESS) {
324 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, 327 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
325 ctxt->c->base_server, 328 ctxt->c->base_server,
326 "[gnutls_cache] error opening cache searcher '%s'", 329 "[gnutls_cache] error opening cache searcher '%s'",
327 ctxt->sc->cache_config); 330 ctxt->sc->cache_config);
328 return -1; 331 apr_pool_destroy(spool);
332 return;
329 } 333 }
330 334
331#define KEYMAX 128
332
333 keylist = apr_palloc(spool, sizeof(dbmkey)*KEYMAX);
334
335 apr_dbm_firstkey(dbm, &dbmkey); 335 apr_dbm_firstkey(dbm, &dbmkey);
336 while (dbmkey.dptr != NULL) { 336 while (dbmkey.dptr != NULL) {
337 apr_dbm_fetch(dbm, dbmkey, &dbmval); 337 apr_dbm_fetch(dbm, dbmkey, &dbmval);
338 if (dbmval.dptr != NULL) { 338 if (dbmval.dptr != NULL && dbmval.dsize >= sizeof(apr_time_t)) {
339 if (dbmval.dsize >= sizeof(apr_time_t)) {
340 memcpy(&dtime, dbmval.dptr, sizeof(apr_time_t)); 339 memcpy(&dtime, dbmval.dptr, sizeof(apr_time_t));
341 if (dtime < ex) { 340
342 should_delete = 1; 341 if (now >= dtime) {
343 } 342 apr_dbm_delete(dbm, dbmkey);
344 } 343 deleted++;
345 else {
346 should_delete = 1;
347 }
348
349 if (should_delete == 1) {
350 should_delete = 0;
351 keylist[keyidx].dptr = apr_palloc(spool, dbmkey.dsize) ;
352 memcpy(keylist[keyidx].dptr, dbmkey.dptr, dbmkey.dsize);
353 keylist[keyidx].dsize = dbmkey.dsize;
354 keyidx++;
355 if (keyidx == KEYMAX) {
356 break;
357 } 344 }
358 } 345 apr_dbm_freedatum( dbm, dbmval);
359 apr_dbm_freedatum( dbm, dbmval); 346 } else {
360 347 apr_dbm_delete(dbm, dbmkey);
348 deleted++;
361 } 349 }
350 total++;
362 apr_dbm_nextkey(dbm, &dbmkey); 351 apr_dbm_nextkey(dbm, &dbmkey);
363 } 352 }
364 apr_dbm_close(dbm); 353 apr_dbm_close(dbm);
365 354
366 rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, 355 ap_log_error(APLOG_MARK, APLOG_DEBUG, rv,
367 APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, spool); 356 ctxt->c->base_server,
368 if (rv != APR_SUCCESS) { 357 "[gnutls_cache] Cleaned up cache '%s'. Deleted %d and left %d",
369 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, 358 ctxt->sc->cache_config, deleted, total-deleted);
370 ctxt->c->base_server,
371 "[gnutls_cache] error opening cache writer '%s'",
372 ctxt->sc->cache_config);
373 return -1;
374 }
375
376 for (i = 0; i < keyidx; i++) {
377 apr_dbm_delete(dbm, keylist[i]);
378 }
379 359
380 apr_dbm_close(dbm);
381 apr_pool_destroy(spool); 360 apr_pool_destroy(spool);
382 361
383 return 0; 362 return;
384} 363}
385 364
386static gnutls_datum_t dbm_cache_fetch(void* baton, gnutls_datum_t key) 365static gnutls_datum_t dbm_cache_fetch(void* baton, gnutls_datum_t key)
@@ -395,7 +374,7 @@ static gnutls_datum_t dbm_cache_fetch(void* baton, gnutls_datum_t key)
395 if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) 374 if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0)
396 return data; 375 return data;
397 376
398 rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, 377 rv = apr_dbm_open_ex(&dbm, ODB, ctxt->sc->cache_config,
399 APR_DBM_READONLY, SSL_DBM_FILE_MODE, ctxt->c->pool); 378 APR_DBM_READONLY, SSL_DBM_FILE_MODE, ctxt->c->pool);
400 if (rv != APR_SUCCESS) { 379 if (rv != APR_SUCCESS) {
401 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, 380 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
@@ -444,13 +423,20 @@ static int dbm_cache_store(void* baton, gnutls_datum_t key,
444 mgs_handle_t *ctxt = baton; 423 mgs_handle_t *ctxt = baton;
445 apr_status_t rv; 424 apr_status_t rv;
446 apr_time_t expiry; 425 apr_time_t expiry;
426 apr_pool_t* spool;
447 427
448 if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) 428 if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0)
449 return -1; 429 return -1;
450 430
431 /* we expire dbm only on every store
432 */
433 dbm_cache_expire(ctxt);
434
435 apr_pool_create(&spool, ctxt->c->pool);
436
451 /* create DBM value */ 437 /* create DBM value */
452 dbmval.dsize = data.size + sizeof(apr_time_t); 438 dbmval.dsize = data.size + sizeof(apr_time_t);
453 dbmval.dptr = (char *)malloc(dbmval.dsize); 439 dbmval.dptr = (char *)apr_palloc(spool, dbmval.dsize);
454 440
455 expiry = apr_time_now() + ctxt->sc->cache_timeout; 441 expiry = apr_time_now() + ctxt->sc->cache_timeout;
456 442
@@ -458,18 +444,14 @@ static int dbm_cache_store(void* baton, gnutls_datum_t key,
458 memcpy((char *)dbmval.dptr+sizeof(apr_time_t), 444 memcpy((char *)dbmval.dptr+sizeof(apr_time_t),
459 data.data, data.size); 445 data.data, data.size);
460 446
461 /* we expire dbm only on every store 447 rv = apr_dbm_open_ex(&dbm, ODB, ctxt->sc->cache_config,
462 */
463 dbm_cache_expire(ctxt);
464
465 rv = apr_dbm_open(&dbm, ctxt->sc->cache_config,
466 APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); 448 APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool);
467 if (rv != APR_SUCCESS) { 449 if (rv != APR_SUCCESS) {
468 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, 450 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
469 ctxt->c->base_server, 451 ctxt->c->base_server,
470 "[gnutls_cache] error opening cache '%s'", 452 "[gnutls_cache] error opening cache '%s'",
471 ctxt->sc->cache_config); 453 ctxt->sc->cache_config);
472 free(dbmval.dptr); 454 apr_pool_destroy(spool);
473 return -1; 455 return -1;
474 } 456 }
475 457
@@ -481,13 +463,13 @@ static int dbm_cache_store(void* baton, gnutls_datum_t key,
481 "[gnutls_cache] error storing in cache '%s'", 463 "[gnutls_cache] error storing in cache '%s'",
482 ctxt->sc->cache_config); 464 ctxt->sc->cache_config);
483 apr_dbm_close(dbm); 465 apr_dbm_close(dbm);
484 free(dbmval.dptr); 466 apr_pool_destroy(spool);
485 return -1; 467 return -1;
486 } 468 }
487 469
488 apr_dbm_close(dbm); 470 apr_dbm_close(dbm);
489 471
490 free(dbmval.dptr); 472 apr_pool_destroy(spool);
491 473
492 return 0; 474 return 0;
493} 475}
@@ -502,7 +484,7 @@ static int dbm_cache_delete(void* baton, gnutls_datum_t key)
502 if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) 484 if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0)
503 return -1; 485 return -1;
504 486
505 rv = apr_dbm_open(&dbm, ctxt->sc->cache_config, 487 rv = apr_dbm_open_ex(&dbm, ODB, ctxt->sc->cache_config,
506 APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); 488 APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool);
507 if (rv != APR_SUCCESS) { 489 if (rv != APR_SUCCESS) {
508 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, 490 ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
@@ -536,7 +518,7 @@ static int dbm_cache_post_config(apr_pool_t *p, server_rec *s,
536 const char* path1; 518 const char* path1;
537 const char* path2; 519 const char* path2;
538 520
539 rv = apr_dbm_open(&dbm, sc->cache_config, APR_DBM_RWCREATE, 521 rv = apr_dbm_open_ex(&dbm, ODB, sc->cache_config, APR_DBM_RWCREATE,
540 SSL_DBM_FILE_MODE, p); 522 SSL_DBM_FILE_MODE, p);
541 523
542 if (rv != APR_SUCCESS) { 524 if (rv != APR_SUCCESS) {
@@ -548,12 +530,12 @@ static int dbm_cache_post_config(apr_pool_t *p, server_rec *s,
548 530
549 apr_dbm_close(dbm); 531 apr_dbm_close(dbm);
550 532
551 apr_dbm_get_usednames(p, sc->cache_config, &path1, &path2); 533 apr_dbm_get_usednames_ex(p, ODB, sc->cache_config, &path1, &path2);
552 534
553 /* The Following Code takes logic directly from mod_ssl's DBM Cache */ 535 /* The Following Code takes logic directly from mod_ssl's DBM Cache */
554#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) 536#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
555 /* Running as Root */ 537 /* Running as Root */
556 if (geteuid() == 0) { 538 if (path1 && geteuid() == 0) {
557 chown(path1, ap_unixd_config.user_id, -1); 539 chown(path1, ap_unixd_config.user_id, -1);
558 if (path2 != NULL) { 540 if (path2 != NULL) {
559 chown(path2, ap_unixd_config.user_id, -1); 541 chown(path2, ap_unixd_config.user_id, -1);
diff --git a/src/gnutls_config.c b/src/gnutls_config.c
index 3ff3b34..d75e785 100644
--- a/src/gnutls_config.c
+++ b/src/gnutls_config.c
@@ -327,9 +327,8 @@ const char *mgs_set_cache(cmd_parms * parms, void *dummy,
327 return err; 327 return err;
328 } 328 }
329 329
330 if (strcasecmp("none", type) == 0) { 330 sc->cache_type = mgs_cache_none;
331 sc->cache_type = mgs_cache_none; 331 if (strcasecmp("dbm", type) == 0) {
332 } else if (strcasecmp("dbm", type) == 0) {
333 sc->cache_type = mgs_cache_dbm; 332 sc->cache_type = mgs_cache_dbm;
334 } 333 }
335#if HAVE_APR_MEMCACHE 334#if HAVE_APR_MEMCACHE
@@ -589,7 +588,7 @@ void *mgs_config_server_create(apr_pool_t * p, server_rec * s)
589 memset( sc->certs_x509, 0, sizeof(sc->certs_x509)); 588 memset( sc->certs_x509, 0, sizeof(sc->certs_x509));
590 sc->certs_x509_num = 0; 589 sc->certs_x509_num = 0;
591 sc->cache_timeout = apr_time_from_sec(300); 590 sc->cache_timeout = apr_time_from_sec(300);
592 sc->cache_type = mgs_cache_dbm; 591 sc->cache_type = mgs_cache_none;
593 sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache"); 592 sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache");
594 593
595 sc->client_verify_mode = GNUTLS_CERT_IGNORE; 594 sc->client_verify_mode = GNUTLS_CERT_IGNORE;