source: mod_gnutls/src/gnutls_cache.c @ 15245bf

debian/masterdebian/stretch-backportsupstream
Last change on this file since 15245bf was 15245bf, checked in by Thomas Klute <thomas2.klute@…>, 3 years ago

Split dbm_cache_fetch() in generic and GnuTLS session specific parts

Like with dbm_cache_store(), a new wrapper function takes care of
session key calculation. This change will make it possible to use the
generic dbm_cache_fetch() for OCSP response caching.

  • Property mode set to 100644
File size: 17.9 KB
RevLine 
[fcb122d]1/**
2 *  Copyright 2004-2005 Paul Querna
[e183628]3 *  Copyright 2008 Nikos Mavrogiannopoulos
4 *  Copyright 2011 Dash Shendy
[8913410]5 *  Copyright 2015-2016 Thomas Klute
[0b3bc05]6 *
7 *  Licensed under the Apache License, Version 2.0 (the "License");
8 *  you may not use this file except in compliance with the License.
9 *  You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 *  Unless required by applicable law or agreed to in writing, software
14 *  distributed under the License is distributed on an "AS IS" BASIS,
15 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 *  See the License for the specific language governing permissions and
17 *  limitations under the License.
18 *
19 */
20
[04e6e65]21#include "gnutls_cache.h"
[0b3bc05]22#include "mod_gnutls.h"
[6e0bfd6]23
24#if HAVE_APR_MEMCACHE
25#include "apr_memcache.h"
26#endif
27
[fcb122d]28#include "apr_dbm.h"
29
[a66e147]30#include "ap_mpm.h"
[0b3bc05]31
[fcb122d]32#include <unistd.h>
33#include <sys/types.h>
34
35#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
36#include "unixd.h"
37#endif
38
[671b64f]39/* it seems the default has some strange errors. Use SDBM
[03a9a6b]40 */
[6e0bfd6]41#define MC_TAG "mod_gnutls:"
[c055502]42#define MC_TAG_LEN sizeof(MC_TAG)
[6e0bfd6]43#define STR_SESSION_LEN (GNUTLS_SESSION_ID_STRING_LEN + MC_TAG_LEN)
44
[7e67487]45#if MODULE_MAGIC_NUMBER_MAJOR < 20081201
46#define ap_unixd_config unixd_config
47#endif
48
[55dc3f0]49#ifdef APLOG_USE_MODULE
50APLOG_USE_MODULE(gnutls);
51#endif
52
[c055502]53char *mgs_session_id2sz(unsigned char *id, int idlen,
[e183628]54        char *str, int strsize) {
55    char *cp;
56    int n;
57
58    cp = str;
59    for (n = 0; n < idlen && n < GNUTLS_MAX_SESSION_ID; n++) {
60        apr_snprintf(cp, strsize - (cp - str), "%02X", id[n]);
61        cp += 2;
62    }
63    *cp = '\0';
64    return str;
[6e0bfd6]65}
[c055502]66
67/* Name the Session ID as:
[c223c85]68 * server:port.SessionID
[c055502]69 * to disallow resuming sessions on different servers
70 */
[e02dd8c]71static int mgs_session_id2dbm(conn_rec * c, unsigned char *id, int idlen,
[e183628]72        apr_datum_t * dbmkey) {
73    char buf[STR_SESSION_LEN];
74    char *sz;
75
76    sz = mgs_session_id2sz(id, idlen, buf, sizeof (buf));
77    if (sz == NULL)
78        return -1;
79
80    dbmkey->dptr =
81            apr_psprintf(c->pool, "%s:%d.%s",
82            c->base_server->server_hostname,
83            c->base_server->port, sz);
84    dbmkey->dsize = strlen(dbmkey->dptr);
85
86    return 0;
[c055502]87}
[7bebb42]88
89#define CTIME "%b %d %k:%M:%S %Y %Z"
[e02dd8c]90
[e183628]91char *mgs_time2sz(time_t in_time, char *str, int strsize) {
92    apr_time_exp_t vtm;
93    apr_size_t ret_size;
94    apr_time_t t;
[e02dd8c]95
96
[e183628]97    apr_time_ansi_put(&t, in_time);
98    apr_time_exp_gmt(&vtm, t);
99    apr_strftime(str, &ret_size, strsize - 1, CTIME, &vtm);
100
101    return str;
[7bebb42]102}
[6e0bfd6]103
[c055502]104#if HAVE_APR_MEMCACHE
[e183628]105
[c055502]106/* Name the Session ID as:
[c223c85]107 * server:port.SessionID
[c055502]108 * to disallow resuming sessions on different servers
109 */
[e183628]110static char *mgs_session_id2mc(conn_rec * c, unsigned char *id, int idlen) {
111    char buf[STR_SESSION_LEN];
112    char *sz;
113
114    sz = mgs_session_id2sz(id, idlen, buf, sizeof (buf));
115    if (sz == NULL)
116        return NULL;
117
118    return apr_psprintf(c->pool, MC_TAG "%s:%d.%s",
119            c->base_server->server_hostname,
120            c->base_server->port, sz);
[42307a9]121}
122
[0b3bc05]123/**
124 * GnuTLS Session Cache using libmemcached
125 *
126 */
127
[a66e147]128/* The underlying apr_memcache system is thread safe... woohoo */
[e02dd8c]129static apr_memcache_t *mc;
[a66e147]130
[e02dd8c]131static int mc_cache_child_init(apr_pool_t * p, server_rec * s,
[e183628]132        mgs_srvconf_rec * sc) {
133    apr_status_t rv = APR_SUCCESS;
134    int thread_limit = 0;
135    int nservers = 0;
136    char *cache_config;
137    char *split;
138    char *tok;
139
140    ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
141
142    /* Find all the servers in the first run to get a total count */
143    cache_config = apr_pstrdup(p, sc->cache_config);
144    split = apr_strtok(cache_config, " ", &tok);
145    while (split) {
146        nservers++;
147        split = apr_strtok(NULL, " ", &tok);
148    }
149
150    rv = apr_memcache_create(p, nservers, 0, &mc);
151    if (rv != APR_SUCCESS) {
152        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
153                "[gnutls_cache] Failed to create Memcache Object of '%d' size.",
154                nservers);
155        return rv;
156    }
157
158    /* Now add each server to the memcache */
159    cache_config = apr_pstrdup(p, sc->cache_config);
160    split = apr_strtok(cache_config, " ", &tok);
161    while (split) {
162        apr_memcache_server_t *st;
163        char *host_str;
164        char *scope_id;
165        apr_port_t port;
166
167        rv = apr_parse_addr_port(&host_str, &scope_id, &port,
168                split, p);
169        if (rv != APR_SUCCESS) {
170            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
171                    "[gnutls_cache] Failed to Parse Server: '%s'",
172                    split);
173            return rv;
174        }
175
176        if (host_str == NULL) {
177            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
178                    "[gnutls_cache] Failed to Parse Server, "
179                    "no hostname specified: '%s'", split);
180            return rv;
181        }
182
183        if (port == 0) {
184            port = 11211; /* default port */
185        }
186
187        /* Should Max Conns be (thread_limit / nservers) ? */
188        rv = apr_memcache_server_create(p,
189                host_str, port,
190                0,
191                1, thread_limit, 600, &st);
192        if (rv != APR_SUCCESS) {
193            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
194                    "[gnutls_cache] Failed to Create Server: %s:%d",
195                    host_str, port);
196            return rv;
197        }
198
199        rv = apr_memcache_add_server(mc, st);
200        if (rv != APR_SUCCESS) {
201            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
202                    "[gnutls_cache] Failed to Add Server: %s:%d",
203                    host_str, port);
204            return rv;
205        }
206
207        split = apr_strtok(NULL, " ", &tok);
208    }
209    return rv;
[32f2e60]210}
[a66e147]211
[e02dd8c]212static int mc_cache_store(void *baton, gnutls_datum_t key,
[e183628]213        gnutls_datum_t data) {
214    apr_status_t rv = APR_SUCCESS;
215    mgs_handle_t *ctxt = baton;
216    char *strkey = NULL;
217    apr_uint32_t timeout;
218
219    strkey = mgs_session_id2mc(ctxt->c, key.data, key.size);
220    if (!strkey)
221        return -1;
222
223    timeout = apr_time_sec(ctxt->sc->cache_timeout);
224
225    rv = apr_memcache_set(mc, strkey, (char *) data.data, data.size, timeout,
226            0);
227
228    if (rv != APR_SUCCESS) {
229        ap_log_error(APLOG_MARK, APLOG_CRIT, rv,
230                ctxt->c->base_server,
231                "[gnutls_cache] error setting key '%s' "
232                "with %d bytes of data", strkey, data.size);
233        return -1;
234    }
235
236    return 0;
[a66e147]237}
238
[e183628]239static gnutls_datum_t mc_cache_fetch(void *baton, gnutls_datum_t key) {
240    apr_status_t rv = APR_SUCCESS;
241    mgs_handle_t *ctxt = baton;
242    char *strkey = NULL;
243    char *value;
244    apr_size_t value_len;
245    gnutls_datum_t data = {NULL, 0};
[e02dd8c]246
[e183628]247    strkey = mgs_session_id2mc(ctxt->c, key.data, key.size);
248    if (!strkey) {
249        return data;
250    }
[e02dd8c]251
[e183628]252    rv = apr_memcache_getp(mc, ctxt->c->pool, strkey,
253            &value, &value_len, NULL);
[e02dd8c]254
[e183628]255    if (rv != APR_SUCCESS) {
[316bd8c]256#if MOD_GNUTLS_DEBUG
[e183628]257        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv,
258                ctxt->c->base_server,
259                "[gnutls_cache] error fetching key '%s' ",
260                strkey);
[316bd8c]261#endif
[e183628]262        data.size = 0;
263        data.data = NULL;
264        return data;
265    }
[a66e147]266
[e183628]267    /* TODO: Eliminate this memcpy. gnutls-- */
268    data.data = gnutls_malloc(value_len);
269    if (data.data == NULL)
270        return data;
[a66e147]271
[e183628]272    data.size = value_len;
273    memcpy(data.data, value, value_len);
[a66e147]274
[e183628]275    return data;
[32f2e60]276}
277
[e183628]278static int mc_cache_delete(void *baton, gnutls_datum_t key) {
279    apr_status_t rv = APR_SUCCESS;
280    mgs_handle_t *ctxt = baton;
281    char *strkey = NULL;
[a66e147]282
[e183628]283    strkey = mgs_session_id2mc(ctxt->c, key.data, key.size);
284    if (!strkey)
285        return -1;
[a66e147]286
[e183628]287    rv = apr_memcache_delete(mc, strkey, 0);
[a66e147]288
[e183628]289    if (rv != APR_SUCCESS) {
290        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv,
291                ctxt->c->base_server,
292                "[gnutls_cache] error deleting key '%s' ",
293                strkey);
294        return -1;
295    }
[a66e147]296
[e183628]297    return 0;
[32f2e60]298}
299
[410d216]300#endif  /* have_apr_memcache */
[6e0bfd6]301
[410d216]302static const char *db_type(mgs_srvconf_rec * sc) {
[e183628]303    if (sc->cache_type == mgs_cache_gdbm)
304        return "gdbm";
305    else
306        return "db";
[771ca63]307}
308
[fcb122d]309#define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD )
310
[f785704]311static void dbm_cache_expire(server_rec *s)
312{
313    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
314        ap_get_module_config(s->module_config, &gnutls_module);
315
[e183628]316    apr_status_t rv;
317    apr_dbm_t *dbm;
318    apr_datum_t dbmkey;
319    apr_datum_t dbmval;
320    apr_time_t dtime;
321    apr_pool_t *spool;
322    int total, deleted;
323
[f785704]324    apr_time_t now = apr_time_now();
[e183628]325
[f785704]326    if (now - sc->last_cache_check < (sc->cache_timeout) / 2)
[e183628]327        return;
328
[f785704]329    sc->last_cache_check = now;
[e183628]330
[f785704]331    apr_pool_create(&spool, NULL);
[e183628]332
333    total = 0;
334    deleted = 0;
335
[f785704]336    rv = apr_dbm_open_ex(&dbm, db_type(sc),
337            sc->cache_config, APR_DBM_RWCREATE,
[e183628]338            SSL_DBM_FILE_MODE, spool);
339    if (rv != APR_SUCCESS) {
[f785704]340        ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, s,
[e183628]341                "[gnutls_cache] error opening cache searcher '%s'",
[f785704]342                sc->cache_config);
[e183628]343        apr_pool_destroy(spool);
344        return;
345    }
346
347    apr_dbm_firstkey(dbm, &dbmkey);
348    while (dbmkey.dptr != NULL) {
349        apr_dbm_fetch(dbm, dbmkey, &dbmval);
350        if (dbmval.dptr != NULL
351                && dbmval.dsize >= sizeof (apr_time_t)) {
352            memcpy(&dtime, dbmval.dptr, sizeof (apr_time_t));
353
354            if (now >= dtime) {
355                apr_dbm_delete(dbm, dbmkey);
356                deleted++;
357            }
358            apr_dbm_freedatum(dbm, dbmval);
359        } else {
360            apr_dbm_delete(dbm, dbmkey);
361            deleted++;
362        }
363        total++;
364        apr_dbm_nextkey(dbm, &dbmkey);
365    }
366    apr_dbm_close(dbm);
367
[f785704]368    ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s,
[e183628]369            "[gnutls_cache] Cleaned up cache '%s'. Deleted %d and left %d",
[f785704]370            sc->cache_config, deleted, total - deleted);
[e183628]371
372    apr_pool_destroy(spool);
373
374    return;
[fcb122d]375}
376
[15245bf]377static gnutls_datum_t dbm_cache_fetch(mgs_handle_t *ctxt, apr_datum_t key)
378{
[e183628]379    gnutls_datum_t data = {NULL, 0};
380    apr_dbm_t *dbm;
381    apr_datum_t dbmval;
382    apr_status_t rv;
383
384    rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc),
385            ctxt->sc->cache_config, APR_DBM_READONLY,
386            SSL_DBM_FILE_MODE, ctxt->c->pool);
387    if (rv != APR_SUCCESS) {
[15245bf]388        ap_log_cerror(APLOG_MARK, APLOG_NOTICE, rv, ctxt->c,
389                      "error opening cache '%s'",
390                      ctxt->sc->cache_config);
[e183628]391        return data;
392    }
393
[15245bf]394    rv = apr_dbm_fetch(dbm, key, &dbmval);
[e183628]395
396    if (rv != APR_SUCCESS) {
397        apr_dbm_close(dbm);
398        return data;
399    }
400
401    if (dbmval.dptr == NULL || dbmval.dsize <= sizeof (apr_time_t)) {
402        apr_dbm_freedatum(dbm, dbmval);
403        apr_dbm_close(dbm);
404        return data;
405    }
406
407    data.size = dbmval.dsize - sizeof (apr_time_t);
408
409    data.data = gnutls_malloc(data.size);
410    if (data.data == NULL) {
411        apr_dbm_freedatum(dbm, dbmval);
412        apr_dbm_close(dbm);
413        return data;
414    }
415
[15245bf]416    ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, ctxt->c,
417                  "fetched %ld bytes from cache",
418                  dbmval.dsize);
419
[e183628]420    memcpy(data.data, dbmval.dptr + sizeof (apr_time_t), data.size);
421
422    apr_dbm_freedatum(dbm, dbmval);
423    apr_dbm_close(dbm);
424
425    return data;
[fcb122d]426}
427
[15245bf]428static gnutls_datum_t dbm_cache_fetch_session(void *baton,
429                                              gnutls_datum_t key)
430{
431    gnutls_datum_t data = {NULL, 0};
432    apr_datum_t dbmkey;
433    mgs_handle_t *ctxt = baton;
434
435    if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0)
436        return data;
437
438    return dbm_cache_fetch(ctxt, dbmkey);
439}
440
[1d1361f]441static int dbm_cache_store(server_rec *s, apr_datum_t key,
[ae08186]442                           gnutls_datum_t data, apr_time_t expiry)
443{
[1d1361f]444    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
445        ap_get_module_config(s->module_config, &gnutls_module);
446
[e183628]447    apr_dbm_t *dbm;
448    apr_datum_t dbmval;
449    apr_status_t rv;
450    apr_pool_t *spool;
451
[1d1361f]452    /* we expire dbm only on every store */
453    dbm_cache_expire(s);
[e183628]454
[1d1361f]455    apr_pool_create(&spool, NULL);
[e183628]456
457    /* create DBM value */
458    dbmval.dsize = data.size + sizeof (apr_time_t);
459    dbmval.dptr = (char *) apr_palloc(spool, dbmval.dsize);
460
[ae08186]461    /* prepend expiration time */
[e183628]462    memcpy((char *) dbmval.dptr, &expiry, sizeof (apr_time_t));
463    memcpy((char *) dbmval.dptr + sizeof (apr_time_t),
464            data.data, data.size);
465
[1d1361f]466    rv = apr_dbm_open_ex(&dbm, db_type(sc),
467                         sc->cache_config, APR_DBM_RWCREATE,
468                         SSL_DBM_FILE_MODE, spool);
469    if (rv != APR_SUCCESS)
470    {
471        ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, s,
472                     "error opening cache '%s'",
473                     sc->cache_config);
[e183628]474        apr_pool_destroy(spool);
475        return -1;
476    }
477
[ae08186]478    rv = apr_dbm_store(dbm, key, dbmval);
[1d1361f]479    if (rv != APR_SUCCESS)
480    {
481        ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s,
482                     "error storing in cache '%s'",
483                     sc->cache_config);
[e183628]484        apr_dbm_close(dbm);
485        apr_pool_destroy(spool);
486        return -1;
487    }
488
[1d1361f]489    ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s,
490                 "stored %ld bytes of data (%ld byte key) in cache '%s'",
491                 dbmval.dsize, key.dsize, sc->cache_config);
492
[e183628]493    apr_dbm_close(dbm);
494
495    apr_pool_destroy(spool);
496
497    return 0;
[fcb122d]498}
499
[ae08186]500static int dbm_cache_store_session(void *baton, gnutls_datum_t key,
501                                   gnutls_datum_t data)
502{
503    mgs_handle_t *ctxt = baton;
504    apr_datum_t dbmkey;
505
506    if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0)
507        return -1;
508
509    apr_time_t expiry = apr_time_now() + ctxt->sc->cache_timeout;
510
[1d1361f]511    return dbm_cache_store(ctxt->c->base_server, dbmkey, data, expiry);
[ae08186]512}
513
[e183628]514static int dbm_cache_delete(void *baton, gnutls_datum_t key) {
515    apr_dbm_t *dbm;
516    apr_datum_t dbmkey;
517    mgs_handle_t *ctxt = baton;
518    apr_status_t rv;
519
520    if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0)
521        return -1;
522
523    rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc),
524            ctxt->sc->cache_config, APR_DBM_RWCREATE,
525            SSL_DBM_FILE_MODE, ctxt->c->pool);
526    if (rv != APR_SUCCESS) {
527        ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
528                ctxt->c->base_server,
529                "[gnutls_cache] error opening cache '%s'",
530                ctxt->sc->cache_config);
531        return -1;
532    }
533
534    rv = apr_dbm_delete(dbm, dbmkey);
535
536    if (rv != APR_SUCCESS) {
537        ap_log_error(APLOG_MARK, APLOG_NOTICE, rv,
538                ctxt->c->base_server,
539                "[gnutls_cache] error deleting from cache '%s'",
540                ctxt->sc->cache_config);
541        apr_dbm_close(dbm);
542        return -1;
543    }
544
545    apr_dbm_close(dbm);
546
547    return 0;
[fcb122d]548}
549
[e02dd8c]550static int dbm_cache_post_config(apr_pool_t * p, server_rec * s,
[e183628]551        mgs_srvconf_rec * sc) {
552    apr_status_t rv;
553    apr_dbm_t *dbm;
554    const char *path1;
555    const char *path2;
[fcb122d]556
[e183628]557    rv = apr_dbm_open_ex(&dbm, db_type(sc), sc->cache_config,
558            APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, p);
[fcb122d]559
[e183628]560    if (rv != APR_SUCCESS) {
561        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
562                "GnuTLS: Cannot create DBM Cache at `%s'",
563                sc->cache_config);
564        return rv;
565    }
[fcb122d]566
[e183628]567    apr_dbm_close(dbm);
[fcb122d]568
[e183628]569    apr_dbm_get_usednames_ex(p, db_type(sc), sc->cache_config, &path1,
570            &path2);
[fcb122d]571
[e183628]572    /* The Following Code takes logic directly from mod_ssl's DBM Cache */
[fcb122d]573#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
[e183628]574    /* Running as Root */
575    if (path1 && geteuid() == 0) {
[422f5b7]576        if (0 != chown(path1, ap_unixd_config.user_id, -1))
577            ap_log_error(APLOG_MARK, APLOG_NOTICE, -1, s,
578                         "GnuTLS: could not chown cache path1 `%s' to uid %d (errno: %d)",
579                         path1, ap_unixd_config.user_id, errno);
[e183628]580        if (path2 != NULL) {
[422f5b7]581            if (0 != chown(path2, ap_unixd_config.user_id, -1))
582                ap_log_error(APLOG_MARK, APLOG_NOTICE, -1, s,
583                             "GnuTLS: could not chown cache path2 `%s' to uid %d (errno: %d)",
584                             path2, ap_unixd_config.user_id, errno);
[e183628]585        }
586    }
[fcb122d]587#endif
588
[e183628]589    return rv;
[fcb122d]590}
591
[e02dd8c]592int mgs_cache_post_config(apr_pool_t * p, server_rec * s,
[e183628]593        mgs_srvconf_rec * sc) {
[040387c]594
595    /* if GnuTLSCache was never explicitly set: */
596    if (sc->cache_type == mgs_cache_unset)
597        sc->cache_type = mgs_cache_none;
598    /* if GnuTLSCacheTimeout was never explicitly set: */
[671b64f]599    if (sc->cache_timeout == -1)
[040387c]600        sc->cache_timeout = apr_time_from_sec(300);
601
[e183628]602    if (sc->cache_type == mgs_cache_dbm
603            || sc->cache_type == mgs_cache_gdbm) {
604        return dbm_cache_post_config(p, s, sc);
605    }
606    return 0;
[fcb122d]607}
608
[e765670]609#if HAVE_APR_MEMCACHE
610int mgs_cache_child_init(apr_pool_t * p,
611                         server_rec * s,
612                         mgs_srvconf_rec * sc)
613#else
614int mgs_cache_child_init(apr_pool_t * p __attribute__((unused)),
615                         server_rec * s __attribute__((unused)),
616                         mgs_srvconf_rec * sc)
617#endif
618{
[e183628]619    if (sc->cache_type == mgs_cache_dbm
620            || sc->cache_type == mgs_cache_gdbm) {
621        return 0;
622    }
[6e0bfd6]623#if HAVE_APR_MEMCACHE
[e183628]624    else if (sc->cache_type == mgs_cache_memcache) {
625        return mc_cache_child_init(p, s, sc);
626    }
[6e0bfd6]627#endif
[e183628]628    return 0;
[6e0bfd6]629}
630
[e02dd8c]631#include <assert.h>
[fcb122d]632
[e183628]633int mgs_cache_session_init(mgs_handle_t * ctxt) {
634    if (ctxt->sc->cache_type == mgs_cache_dbm
635            || ctxt->sc->cache_type == mgs_cache_gdbm) {
636        gnutls_db_set_retrieve_function(ctxt->session,
[15245bf]637                dbm_cache_fetch_session);
[e183628]638        gnutls_db_set_remove_function(ctxt->session,
639                dbm_cache_delete);
640        gnutls_db_set_store_function(ctxt->session,
[ae08186]641                dbm_cache_store_session);
[e183628]642        gnutls_db_set_ptr(ctxt->session, ctxt);
643    }
[6e0bfd6]644#if HAVE_APR_MEMCACHE
[e183628]645    else if (ctxt->sc->cache_type == mgs_cache_memcache) {
646        gnutls_db_set_retrieve_function(ctxt->session,
647                mc_cache_fetch);
648        gnutls_db_set_remove_function(ctxt->session,
649                mc_cache_delete);
650        gnutls_db_set_store_function(ctxt->session,
651                mc_cache_store);
652        gnutls_db_set_ptr(ctxt->session, ctxt);
653    }
[6e0bfd6]654#endif
[42307a9]655
[e183628]656    return 0;
[32f2e60]657}
Note: See TracBrowser for help on using the repository browser.