1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

g10: Make the keyblock cache per-handle rather than global.

* g10/keydb.c (keyblock_cache): Don't declare this variable.  Instead...
(struct keyblock_cache): ... turn its type into this first class
object...
(struct keydb_handle): ... and instantiate it once per database
handle.  Update all users.
(keydb_rebuild_caches): Don't invalidate the keyblock cache.

--
Signed-off-by: Neal H. Walfield <neal@g10code.com>.
This commit is contained in:
Neal H. Walfield 2015-08-31 13:57:07 +02:00
parent f076fa190e
commit 60bc518645

View File

@ -62,6 +62,28 @@ static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
static int used_resources; static int used_resources;
static void *primary_keyring=NULL; static void *primary_keyring=NULL;
/* This is a simple cache used to return the last result of a
successful fingerprint search. This works only for keybox resources
because (due to lack of a copy_keyblock function) we need to store
an image of the keyblock which is fortunately instantly available
for keyboxes. */
enum keyblock_cache_states {
KEYBLOCK_CACHE_EMPTY,
KEYBLOCK_CACHE_PREPARED,
KEYBLOCK_CACHE_FILLED
};
struct keyblock_cache {
enum keyblock_cache_states state;
byte fpr[MAX_FINGERPRINT_LEN];
iobuf_t iobuf; /* Image of the keyblock. */
u32 *sigstatus;
int pk_no;
int uid_no;
};
struct keydb_handle struct keydb_handle
{ {
/* When we locked all of the resources in ACTIVE (using keyring_lock /* When we locked all of the resources in ACTIVE (using keyring_lock
@ -94,6 +116,10 @@ struct keydb_handle
/* The number of resources in ACTIVE. */ /* The number of resources in ACTIVE. */
int used; int used;
/* Cache of the last found and parsed key block (only used for
keyboxes, not keyrings). */
struct keyblock_cache keyblock_cache;
/* Copy of ALL_RESOURCES when keydb_new is called. */ /* Copy of ALL_RESOURCES when keydb_new is called. */
struct resource_item active[MAX_KEYDB_RESOURCES]; struct resource_item active[MAX_KEYDB_RESOURCES];
}; };
@ -126,27 +152,6 @@ struct kid_not_found_cache_bucket
}; };
/* This is a simple cache used to return the last result of a
successful fingerprint search. This works only for keybox resources
because (due to lack of a copy_keyblock function) we need to store
an image of the keyblock which is fortunately instantly available
for keyboxes. */
enum keyblock_cache_states {
KEYBLOCK_CACHE_EMPTY,
KEYBLOCK_CACHE_PREPARED,
KEYBLOCK_CACHE_FILLED
};
struct {
enum keyblock_cache_states state;
byte fpr[MAX_FINGERPRINT_LEN];
iobuf_t iobuf; /* Image of the keyblock. */
u32 *sigstatus;
int pk_no;
int uid_no;
} keyblock_cache;
static int lock_all (KEYDB_HANDLE hd); static int lock_all (KEYDB_HANDLE hd);
static void unlock_all (KEYDB_HANDLE hd); static void unlock_all (KEYDB_HANDLE hd);
@ -233,13 +238,13 @@ kid_not_found_flush (void)
static void static void
keyblock_cache_clear (void) keyblock_cache_clear (struct keydb_handle *hd)
{ {
keyblock_cache.state = KEYBLOCK_CACHE_EMPTY; hd->keyblock_cache.state = KEYBLOCK_CACHE_EMPTY;
xfree (keyblock_cache.sigstatus); xfree (hd->keyblock_cache.sigstatus);
keyblock_cache.sigstatus = NULL; hd->keyblock_cache.sigstatus = NULL;
iobuf_close (keyblock_cache.iobuf); iobuf_close (hd->keyblock_cache.iobuf);
keyblock_cache.iobuf = NULL; hd->keyblock_cache.iobuf = NULL;
} }
@ -1124,23 +1129,23 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
if (DBG_CLOCK) if (DBG_CLOCK)
log_clock ("keydb_get_keybock enter"); log_clock ("keydb_get_keybock enter");
if (keyblock_cache.state == KEYBLOCK_CACHE_FILLED) if (hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED)
{ {
err = iobuf_seek (keyblock_cache.iobuf, 0); err = iobuf_seek (hd->keyblock_cache.iobuf, 0);
if (err) if (err)
{ {
log_error ("keydb_get_keyblock: failed to rewind iobuf for cache\n"); log_error ("keydb_get_keyblock: failed to rewind iobuf for cache\n");
keyblock_cache_clear (); keyblock_cache_clear (hd);
} }
else else
{ {
err = parse_keyblock_image (keyblock_cache.iobuf, err = parse_keyblock_image (hd->keyblock_cache.iobuf,
keyblock_cache.pk_no, hd->keyblock_cache.pk_no,
keyblock_cache.uid_no, hd->keyblock_cache.uid_no,
keyblock_cache.sigstatus, hd->keyblock_cache.sigstatus,
ret_kb); ret_kb);
if (err) if (err)
keyblock_cache_clear (); keyblock_cache_clear (hd);
if (DBG_CLOCK) if (DBG_CLOCK)
log_clock (err? "keydb_get_keyblock leave (cached, failed)" log_clock (err? "keydb_get_keyblock leave (cached, failed)"
: "keydb_get_keyblock leave (cached)"); : "keydb_get_keyblock leave (cached)");
@ -1171,13 +1176,13 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
{ {
err = parse_keyblock_image (iobuf, pk_no, uid_no, sigstatus, err = parse_keyblock_image (iobuf, pk_no, uid_no, sigstatus,
ret_kb); ret_kb);
if (!err && keyblock_cache.state == KEYBLOCK_CACHE_PREPARED) if (!err && hd->keyblock_cache.state == KEYBLOCK_CACHE_PREPARED)
{ {
keyblock_cache.state = KEYBLOCK_CACHE_FILLED; hd->keyblock_cache.state = KEYBLOCK_CACHE_FILLED;
keyblock_cache.sigstatus = sigstatus; hd->keyblock_cache.sigstatus = sigstatus;
keyblock_cache.iobuf = iobuf; hd->keyblock_cache.iobuf = iobuf;
keyblock_cache.pk_no = pk_no; hd->keyblock_cache.pk_no = pk_no;
keyblock_cache.uid_no = uid_no; hd->keyblock_cache.uid_no = uid_no;
} }
else else
{ {
@ -1189,8 +1194,8 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
break; break;
} }
if (keyblock_cache.state != KEYBLOCK_CACHE_FILLED) if (hd->keyblock_cache.state != KEYBLOCK_CACHE_FILLED)
keyblock_cache_clear (); keyblock_cache_clear (hd);
if (DBG_CLOCK) if (DBG_CLOCK)
log_clock (err? "keydb_get_keyblock leave (failed)" log_clock (err? "keydb_get_keyblock leave (failed)"
@ -1298,7 +1303,7 @@ keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
return gpg_error (GPG_ERR_INV_ARG); return gpg_error (GPG_ERR_INV_ARG);
kid_not_found_flush (); kid_not_found_flush ();
keyblock_cache_clear (); keyblock_cache_clear (hd);
if (hd->found < 0 || hd->found >= hd->used) if (hd->found < 0 || hd->found >= hd->used)
return gpg_error (GPG_ERR_VALUE_NOT_FOUND); return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
@ -1349,7 +1354,7 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
return gpg_error (GPG_ERR_INV_ARG); return gpg_error (GPG_ERR_INV_ARG);
kid_not_found_flush (); kid_not_found_flush ();
keyblock_cache_clear (); keyblock_cache_clear (hd);
if (opt.dry_run) if (opt.dry_run)
return 0; return 0;
@ -1409,7 +1414,7 @@ keydb_delete_keyblock (KEYDB_HANDLE hd)
return gpg_error (GPG_ERR_INV_ARG); return gpg_error (GPG_ERR_INV_ARG);
kid_not_found_flush (); kid_not_found_flush ();
keyblock_cache_clear (); keyblock_cache_clear (hd);
if (hd->found < 0 || hd->found >= hd->used) if (hd->found < 0 || hd->found >= hd->used)
return gpg_error (GPG_ERR_VALUE_NOT_FOUND); return gpg_error (GPG_ERR_VALUE_NOT_FOUND);
@ -1497,8 +1502,6 @@ keydb_rebuild_caches (int noisy)
{ {
int i, rc; int i, rc;
keyblock_cache_clear ();
for (i=0; i < used_resources; i++) for (i=0; i < used_resources; i++)
{ {
if (!keyring_is_writable (all_resources[i].token)) if (!keyring_is_writable (all_resources[i].token))
@ -1537,7 +1540,7 @@ keydb_search_reset (KEYDB_HANDLE hd)
if (!hd) if (!hd)
return gpg_error (GPG_ERR_INV_ARG); return gpg_error (GPG_ERR_INV_ARG);
keyblock_cache_clear (); keyblock_cache_clear (hd);
if (DBG_CLOCK) if (DBG_CLOCK)
log_clock ("keydb_search_reset"); log_clock ("keydb_search_reset");
@ -1652,8 +1655,8 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
&& ndesc == 1 && ndesc == 1
&& (desc[0].mode == KEYDB_SEARCH_MODE_FPR20 && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
|| desc[0].mode == KEYDB_SEARCH_MODE_FPR) || desc[0].mode == KEYDB_SEARCH_MODE_FPR)
&& keyblock_cache.state == KEYBLOCK_CACHE_FILLED && hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED
&& !memcmp (keyblock_cache.fpr, desc[0].u.fpr, 20)) && !memcmp (hd->keyblock_cache.fpr, desc[0].u.fpr, 20))
{ {
/* (DESCINDEX is already set). */ /* (DESCINDEX is already set). */
if (DBG_CLOCK) if (DBG_CLOCK)
@ -1694,14 +1697,14 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
? gpg_error (GPG_ERR_NOT_FOUND) ? gpg_error (GPG_ERR_NOT_FOUND)
: rc); : rc);
keyblock_cache_clear (); keyblock_cache_clear (hd);
if (!hd->no_caching if (!hd->no_caching
&& !rc && !rc
&& ndesc == 1 && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20 && ndesc == 1 && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
|| desc[0].mode == KEYDB_SEARCH_MODE_FPR)) || desc[0].mode == KEYDB_SEARCH_MODE_FPR))
{ {
keyblock_cache.state = KEYBLOCK_CACHE_PREPARED; hd->keyblock_cache.state = KEYBLOCK_CACHE_PREPARED;
memcpy (keyblock_cache.fpr, desc[0].u.fpr, 20); memcpy (hd->keyblock_cache.fpr, desc[0].u.fpr, 20);
} }
if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND